Hibernate/JPA 合并后获取数据库中具有默认值的列的值
Hibernate/JPA get value of column with default value in database after merge
案例:我想在合并对象后获取映射到数据库端具有默认值的列的字段值。
Table:
CREATE TABLE IF NOT EXISTS `db`.`OBJECT` (
`OBJECT_ID` INT NOT NULL AUTO_INCREMENT,
`NAME` VARCHAR(64) NULL,
`CREATED_ON` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
`EDITED_ON` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
Class:
@Entity
@Table(name="OBJECT")
public class SomeObject {
private int id;
private String name;
private Timestamp createdOn;
private Timestamp editedOn;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "CREATED_ON", insertable = false, updatable = false)
public Timestamp getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Timestamp createdOn) {
this.createdOn = createdOn;
}
@Column(name = "EDITED_ON", insertable = false, updatable = false)
public Timestamp getEditedOn() {
return editedOn;
}
public void setEditedOn(Timestamp editedOn) {
this.editedOn = editedOn;
}
}
DAO:
@Transactional
public class ObjectDAO {
@PersistenceContext
private EntityManager entityManager;
public someObject merge(someObject someObject) {
return entityManager.merge(someObject);
}
}
我想做的事情:
SomeObject someObject = new SomeObject();
someObject.setName("name");
SomeObject insertedObject = objectDAO.merge(someObject);
System.out.println(insertedObject.getId());
System.out.println(insertedObject.getEditedOn());
结果:
对象被插入数据库,所有默认值都正确生成。
问题:
为什么第二个 println 打印 null,但第一个 println 打印插入数据库的 Id 的正确值?
在执行此行之前:
System.out.println(insertedObject.getEditedOn());
您必须通过调用 "flush"(同步)您的更新:entityManager.flush();
经过更多研究,我发现如果我使用默认数据库值,则不可能将它们包含在从合并返回的实体中。就那么简单。我更改了方法并使用 @PrePersist
和 @PreUpdate
注释。应该是这样的:
@Entity
@Table(name="OBJECT")
public class SomeObject {
private int id;
private String name;
private Timestamp createdOn;
private Timestamp editedOn;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "CREATED_ON")
public Timestamp getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Timestamp createdOn) {
this.createdOn = createdOn;
}
@Column(name = "EDITED_ON")
public Timestamp getEditedOn() {
return editedOn;
}
public void setEditedOn(Timestamp editedOn) {
this.editedOn = editedOn;
}
@PrePersist
public void setDates() {
createdOn = LocalDateTime.now();
editedOn = LocalDateTime.now();
}
@PreUpdate
public void setEditedOn() {
editedOn = LocalDateTime.now();
}
}
为什么返回的实体中有正确的 ID?因为它实际上是由Hibernate生成的@GeneratedValue(strategy = GenerationType.IDENTITY)
案例:我想在合并对象后获取映射到数据库端具有默认值的列的字段值。
Table:
CREATE TABLE IF NOT EXISTS `db`.`OBJECT` (
`OBJECT_ID` INT NOT NULL AUTO_INCREMENT,
`NAME` VARCHAR(64) NULL,
`CREATED_ON` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
`EDITED_ON` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
Class:
@Entity
@Table(name="OBJECT")
public class SomeObject {
private int id;
private String name;
private Timestamp createdOn;
private Timestamp editedOn;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "CREATED_ON", insertable = false, updatable = false)
public Timestamp getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Timestamp createdOn) {
this.createdOn = createdOn;
}
@Column(name = "EDITED_ON", insertable = false, updatable = false)
public Timestamp getEditedOn() {
return editedOn;
}
public void setEditedOn(Timestamp editedOn) {
this.editedOn = editedOn;
}
}
DAO:
@Transactional
public class ObjectDAO {
@PersistenceContext
private EntityManager entityManager;
public someObject merge(someObject someObject) {
return entityManager.merge(someObject);
}
}
我想做的事情:
SomeObject someObject = new SomeObject();
someObject.setName("name");
SomeObject insertedObject = objectDAO.merge(someObject);
System.out.println(insertedObject.getId());
System.out.println(insertedObject.getEditedOn());
结果: 对象被插入数据库,所有默认值都正确生成。
问题: 为什么第二个 println 打印 null,但第一个 println 打印插入数据库的 Id 的正确值?
在执行此行之前:
System.out.println(insertedObject.getEditedOn());
您必须通过调用 "flush"(同步)您的更新:entityManager.flush();
经过更多研究,我发现如果我使用默认数据库值,则不可能将它们包含在从合并返回的实体中。就那么简单。我更改了方法并使用 @PrePersist
和 @PreUpdate
注释。应该是这样的:
@Entity
@Table(name="OBJECT")
public class SomeObject {
private int id;
private String name;
private Timestamp createdOn;
private Timestamp editedOn;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "CREATED_ON")
public Timestamp getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Timestamp createdOn) {
this.createdOn = createdOn;
}
@Column(name = "EDITED_ON")
public Timestamp getEditedOn() {
return editedOn;
}
public void setEditedOn(Timestamp editedOn) {
this.editedOn = editedOn;
}
@PrePersist
public void setDates() {
createdOn = LocalDateTime.now();
editedOn = LocalDateTime.now();
}
@PreUpdate
public void setEditedOn() {
editedOn = LocalDateTime.now();
}
}
为什么返回的实体中有正确的 ID?因为它实际上是由Hibernate生成的@GeneratedValue(strategy = GenerationType.IDENTITY)