如何使用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(); }
- 如何在JSP页面上映射一对多关系并在提交页面时存储它们?
- Hibernate Session方法saveOrUpdate()和merge()之间有什么区别?
- 插入时如何忽略重复行
- Spring 4 + Hibernate 5 = org.springframework.orm.jpa.EntityManagerHolder无法强制转换为org.springframework.orm.hibernate5.SessionHolder
- 使用Spring Boot + Hibernate + MySql运行MVC应用程序
- JPA。 JoinTable和两个JoinColumns
- Hibernate Criteria和多个join
- 为什么hibernate执行两个查询以急切加载@OneToOne双向关联?
- Spring Data Repository不会删除ManyToOne Entity