2014-02-26 9 views
15

ich ein Unternehmen haben zu aktualisieren und einen JUnit, möchte ich, dass Update-Methode funktioniert prima testen, aber wenn ich Speichermethode von CrudRepository aufrufen bekomme ich einen neuen Eintrag in meinem Tisch statt der aktualisierte Entität, wie ein Unternehmen mit Federdaten JPA

Das ist meine Einheit:

@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 
} 

Das ist meine Dienstklasse ist:

@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()); 
    } 
} 
:

@Service 
public class PersonServiceImpl implements PersonService { 

    @Autowired 
    private PersonRepository personRepository; 

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

     return personRepository.save(oldPerson); 
    } 
} 

Das ist mein Repository

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

Das ist mein Test Ich gehe davon aus sein sollte

Vielen Dank im Voraus

+0

Stellen Sie sicher, welche Werte eingestellt sind. Sie können dies überprüfen, indem Sie diese Werte vor dem Aufruf von save() protokollieren. –

+0

Sie haben vergessen, 'equals() 'und' hashcode() 'in Person zu implementieren. Berücksichtigen Sie bei der Implementierung nur das Feld 'id'. Das sollte dein Problem lösen. –

Antwort

1

Ich denke, das Repository

public interface PersonRepository extends CrudRepository<Person, Integer> { 

Als Ihr Id Integer nicht String ist, auch, dass Ihr

personService.createPerson(person); 

intern speichern Methode des Repo verwenden .

Mein zweiter Rat ist die

@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)} 

Dies bedeutet, dass die App Kontext erneut erzeugt werden müssen auch Bohnen, so stellen Sie sicher, dass Ihre Konfiguration in persistence.xml nicht h2bml gesetzt zu haben zu erstellen. Denken Sie auch daran, die Spülmethode in Ihrem Service aufzurufen.

+0

Ich verwende @DirtiesContext (classMode = ClassMode.AFTER_EACH_TEST_METHOD)}, weil ich mehrere Integration Test und dies erzeugt Konflikte zwischen ihnen. Ich sehe nicht, warum sollte ich in meinem Dienst bündig anrufen? Ich denke, Frühjahrsdaten machen das für dich, oder? – nspessot

24

Das Problem ist in Ihrer updatePerson Methode in der Dienstklasse. Speziell:

return personRepository.save(oldPerson); 

Alles, was Sie gerade tun, ist eine Person zu speichern. Deshalb erstellt es einen zweiten Eintrag.
Was Sie tun sollten, ist die oldPerson erste finden,

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

dann seine Attribute aktualisieren, und speichern Sie es dann wie zuvor. Hoffe, dass hilft.

+2

Ich denke, diese Antwort ist falsch. In spring-data-jpa aktualisiert das Speichern das Objekt tatsächlich, wie in 5.2.1 in diesem Dokument angegeben. http://docs.spring.io/spring-data/jpa/docs/current/reference/html/ (Wenn es wahr wäre, wäre es eine schlechte Nachricht sein. Dann, wenn Sie ein Unternehmen mit vielen Bereichen durch eine Feder empfangen Mvc-Controller, können Sie einfach nicht speichern, würden Sie alle Felder festgelegt haben, die viel boilerpate Code bedeuten würde) – Adamsan

+0

@Adamsan ja es sollte mit 'save' wie diese funktionieren. ' public S speichern (S Entität) { if (entityInformation.isNew (entity)) { em.persist (entity); Rückgabeeinheit; } else { Rückgabe em.merge (Entität); } } ' aber es ist nicht so gut für mich arbeiten. Ich denke, die obige Antwort hilft – kittu

+0

@Adamsan Ich denke, das ist nicht korrekt 'entityInformation.isNew (entity)' – kittu

5

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(); 
    } 
} 
0

Zwei Möglichkeiten, um diese Arbeit

Überschreibung 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 equals und hashCode Methoden in der Entity-Klasse wie unten

außer Kraft setzen müssen, um
@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(); 
} 
Verwandte Themen