合并后,Hibernate / JPA在数据库中获取具有默认值的列的值

时间:2016-07-19 21:45:51

标签: java hibernate jpa persistence

案例:我希望在合并对象后得到映射到数据库端默认值的列的字段值。

表格

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
)

类别:

@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的正确值?

3 个答案:

答案 0 :(得分:1)

经过更多研究后,我发现如果我使用默认数据库值,则无法在合并返回的实体中使用它们。就那么简单。我更改了apporach并使用@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)

答案 1 :(得分:0)

尝试在合并后提交,因为我认为这还没有在数据库中hibernate仍然将其保留在内存中

答案 2 :(得分:0)

在执行此行之前:

  

的System.out.println(insertedObject.getEditedOn());

您必须致电:entityManager.flush();

“刷新”(同步)您的更新