如何使用spring data jpa更新实体

我有一个实体和一个Junit,我想测试更新方法工作正常,但是当我从CrudRepository调用save方法时,我在我的表中得到一个新条目而不是更新的实体。

这是我的实体:

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

这是我的服务类:

 @Service public class PersonServiceImpl implements PersonService { @Autowired private PersonRepository personRepository; @Override public Person updatePerson(Person oldPerson) throws Exception { return personRepository.save(oldPerson); } } 

这是我的存储库

 public interface PersonRepository extends CrudRepository { } 

这是我的测试:

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

提前致谢

问题出在您的服务类中的updatePerson方法中。 特别:

 return personRepository.save(oldPerson); 

你目前正在做的就是拯救一个人。 这就是它创建第二个条目的原因。
你应该做的是先找到oldPerson,

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

然后更新其属性,然后像以前一样保存它。 希望有所帮助。

您必须在Person类中实现equals()hashCode()

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

我认为存储库应该是

 public interface PersonRepository extends CrudRepository { 

由于你的Id是整数而不是字符串,我也认为你的

 personService.createPerson(person); 

内部使用repo的save方法。

我的第二个建议是

 @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)} 

这意味着还需要再次生成应用程序上下文,因此请确保您在persistence.xml中的配置没有将h2bml设置为create。 还要考虑在您的服务中调用flush方法。

两种方法使这项工作

将compareTo方法覆盖为

 @Entity(name = "PERSON") public class Person implements Comparable{ //... all your attributes goes here private Integer id; @Override public int compareTo(Person person) { return this.getId().compareTo(person.getId()); }} 

要么

您需要在实体类中重写equals和hashcode方法,如下所示

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