我有一个实体和一个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<Person, String> {
}
这是我的测试:
@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());
}
}
提前致谢
答案 0 :(得分:27)
问题在于服务类中的updatePerson方法。具体做法是:
return personRepository.save(oldPerson);
您目前所做的只是保存一个人。这就是它创建第二个条目的原因 你应该做的是先找到oldPerson,
Person p = personRepository.findOne(oldPerson.getId())
然后更新其属性,然后像以前一样保存它。 希望有所帮助。
答案 1 :(得分:5)
您必须在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();
}
}
答案 2 :(得分:1)
我认为存储库应该是
public interface PersonRepository extends CrudRepository<Person, Integer> {
由于你的Id是整数而不是字符串,我还假设你的
personService.createPerson(person);
内部使用回购的保存方法。
我的第二个建议是
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)}
这意味着还需要再次生成应用程序上下文,因此请确保您在persistence.xml中的配置没有将h2bml设置为create。 另请考虑在您的服务中调用flush方法。
答案 3 :(得分:0)
使这项工作的两种方法
将compareTo方法覆盖为
@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());
}}
或
您需要在实体类中重写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();
}
答案 4 :(得分:0)
无需为此执行任何复杂的操作。 在您的服务类中,您可以执行以下操作。
<script>
$('#workshops').on('hide.bs.modal', function () {
stopVideo("resp-iframe");
});
</script>
这解决了在数据库中创建新条目并使用与该人相关联的ID更新相同内容的问题。