我们在项目中使用Hibernate 5.2.17,并在@PreUpdate
实体回调中填充上次修改日期。
经过长时间的调试会话后,
对回调中的实体所做的更改不会不持久保存在数据库级别。
我本来打算将它作为Hibernate的错误,但在此之前,我们会收到有关我们是否做错了事的反馈。
实体
@Entity(name = "Person")
private static class Person {
@Id
@GeneratedValue
private int id;
private String name;
private Instant createdAt;
private Instant lastUpdatedAt;
@ElementCollection(fetch = FetchType.LAZY)
private List<String> tags;
@Lob
@Basic(fetch = FetchType.LAZY)
private ByteBuffer image;
@PrePersist
void beforeCreate() {
createdAt = Instant.now();
}
@PreUpdate
void beforeUpdate() {
lastUpdatedAt = Instant.now();
}
}
测试(缩写)
@Test
public void testPreUpdateModificationDate() throws Exception {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
Person p = new Person();
em.persist(p);
em.getTransaction().commit();
int personId = p.id;
em.refresh(p);
p = em.find(Person.class, personId);
assertNotNull(p);
assertNotNull(p.createdAt);
assertNull(p.lastUpdatedAt);
p.name = "New Name";
em.getTransaction().begin();
em.merge(p);
em.getTransaction().commit();
assertEquals(p.name, "New Name");
em.refresh(p);
p = em.find(Person.class, personId);
// the last line fails
assertNotNull(p.lastUpdatedAt);
}
从Person
中删除延迟加载的属性之一后,测试将成功运行。
在调试中,看起来好像为实体更新生成的SQL并不认为@PreUpdate
中更改的字段是脏字段。 org.hibernate.persister.entity.AbstractPersister
类具有用于“动态更新”的不同SQL生成,当字节码增强处于活动状态并且存在1个以上的访存组时,将自动选择该类。
答案 0 :(得分:0)
对我有用:不确定是什么问题,但是您有很多奇怪的事情。也许从这个简单的示例开始,然后扩展到您的代码以发现不同之处:
tx.begin();
Person p = new Person();
em.persist(p);
tx.commit();
System.out.println(p);
tx.begin();
p.setName( "New Name" );
tx.commit();
System.out.println(p);
答案 1 :(得分:0)
此问题已在5.3.3的Hibernate中修复。