wake-up-neo.com

so aktualisieren Sie eine Entität mit Spring Data JPA

Ich habe ein Entity und ein Junit, ich möchte testen, ob die Update-Methode einwandfrei funktioniert, aber wenn ich die Save-Methode von CrudRepository aus aufrufe, erhalte ich einen neuen Eintrag in meiner Tabelle anstelle der aktualisierten Entity.

Dies ist meine Entität:

@Entity(name = "PERSON")
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "PERSON_ID")
    private Integer id;
    @Column(name = "FIRST_NAME")
    private String firstName;
    @Column(name = "LAST_NAME")
    private String lastName;
//getters and setters
}

Dies ist meine Serviceklasse:

@Service
public class PersonServiceImpl implements PersonService {

    @Autowired
    private PersonRepository personRepository;

    @Override
    public Person updatePerson(Person oldPerson) throws Exception { 

        return personRepository.save(oldPerson);
    }
}

Dies ist mein Repository

public interface PersonRepository extends CrudRepository<Person, String> {
}

Das ist mein Test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { JPAConfigurationTest.class })
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
@Transactional
public class UpdatePersonServiceIntegrationTest {
        @Autowired
    PersonService personService;

        @Before
    public void setUp() throws Exception {
        Person person = new Person(1);
        person.setFirstName("Nicolas");
        person.setLastName("Spessot");

        personService.createPerson(person); //This invokes save
    }

        @Test
    public void updatingPerson() throws Exception{
        Person person = new Person(1);
        person.setFirstName("Juan");
        person.setLastName("Riquelme");

        personService.updatePerson(person);

        Person retrieved = personService.retrievePerson(1); //This invokes findOne

        assertEquals(1, person.getId());
        assertEquals("Juan", person.getFirstName());
        assertEquals("Riquelme", person.getLastName());
    }
}

Danke im Voraus

16
nspessot

Das Problem liegt in Ihrer updatePerson-Methode in Ihrer Serviceklasse. Speziell:

return personRepository.save(oldPerson);

Alles, was Sie gerade tun, ist das Speichern einer Person. Deshalb wird ein zweiter Eintrag erstellt.
Was Sie tun sollten, ist zuerst den altenPersonen zu finden. 

Person p = personRepository.findOne(oldPerson.getId())

aktualisieren Sie dann die Attribute, und speichern Sie sie dann wie zuvor .. _. Hoffe, das hilft.

25
chinesewhiteboi

Sie müssen equals() und hashCode() in der Klasse Person implementieren.

@Entity(name = "PERSON")
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "PERSON_ID")
    private Integer id;
    @Column(name = "FIRST_NAME")
    private String firstName;
    @Column(name = "LAST_NAME")
    private String lastName;
    //getters and setters

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (id == null || obj == null || getClass() != obj.getClass())
            return false;
        Person that = (Person) obj;
        return id.equals(that.id);
    }
    @Override
    public int hashCode() {
        return id == null ? 0 : id.hashCode();
    }
}
5
ciri-cuervo

Ich denke das Repository sollte sein

public interface PersonRepository extends CrudRepository<Person, Integer> {

Da Ihre ID nicht Integer ist, sondern auch String

personService.createPerson(person); 

Interne Save-Methode des Repos verwenden.

Mein zweiter Rat ist das 

@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)}

Dies bedeutet, dass der App-Kontext erneut generiert werden muss, auch Beans. Vergewissern Sie sich daher, dass in Ihrer Konfiguration in persistence.xml nicht h2bml für create .. festgelegt ist. Denken Sie auch daran, die flush-Methode in Ihrem Service aufzurufen.

1
Koitoer

Zwei Möglichkeiten, dies zu erreichen

override compareTo-Methode als 

@Entity(name = "PERSON")
public class Person implements Comparable<Person>{
 //... all your attributes goes here
 private Integer id;

 @Override
public int compareTo(Person person) {
   return this.getId().compareTo(person.getId());
}} 

oder 

sie müssen in ihrer Entitätsklasse wie folgt Equals- und Hashcode-Methoden überschreiben 

 @Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (id == null || obj == null || getClass() != obj.getClass())
        return false;
    Person that = (Person) obj;
    return id.equals(that.id);
}
@Override
public int hashCode() {
    return id == null ? 0 : id.hashCode();
}