当前位置: 首页 > 知识库问答 >
问题:

Hibernate/JPA在合并后使用数据库中的默认值获取列的值

慕光赫
2023-03-14

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

表:

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

共有2个答案

古扬
2023-03-14

经过更多的研究,我发现若我使用默认的数据库值,那个么在从合并返回的实体中就不可能有它们。就这么简单。我更改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(策略=GenerationType.IDENTITY)

厉永宁
2023-03-14

在执行这一行之前:

System.out.printlnbject.getEditedOn();

您必须通过调用entityManager来“刷新”(同步)更新。冲洗()

 类似资料:
  • 问题内容: 我正在使用Oracle数据库。 我想使用Java JDBC获得分配给列的默认值。 但是using 没有提供任何方法来获取列的默认值。 所以,请告诉我任何想法。提前致谢。 问题答案: 您可以运行此查询

  • 问题内容: 我执行选择以获取表的结构。我想获取有关列的信息,例如其名称,是否为null或是否为主键。 但是对于默认值,我得到的是id ..类似454545454的东西,但是我想得到的值是“ xxxx”。要搜索的表是什么,或者将该ID转换为值的函数是什么。谢谢 问题答案: 您可以执行此操作(只需执行SELECT *,这样您就可以看到所有可用信息): 结果集中包括“ COLUMN_DEFAULT”列。

  • 问题内容: 我在数据库中有一列,默认值为。我正在寻找一种方法来插入该默认值,而我并未向应用程序端的相应属性提供任何东西。顺便说一句,我正在使用基于注释的配置。 有什么建议吗? 问题答案: 即使将date列定义为dbms端,date列在插入时仍会得到值的原因是,仅当在查询中未为该列提供值时,才使用该列的值。这意味着即使已经给出了它也不能出现在句子中。 如果要在DBMS端使用,则应配置with ,以使

  • 问题内容: 我在模型上有一个字段,其内容是: 然后,我将模型更改为: 当我运行以检查迁移时,发现以下更改: 我不理解为什么Django在表中应用a ,因为我正在 创建 默认值。如果这是正确的,Django如何实现默认值? 有关我的工具的信息: PostgreSQL 9.5; Django 1.11b1; 问题答案: 从ln开始的对django / db / backends / base / sc

  • 问题内容: 我有一个实体,该实体具有必须从序列中设置的NON-ID字段。目前,我获取序列的第一个值,将其存储在客户端,然后根据该值进行计算。 但是,我正在寻找一种“更好”的方法。我实现了一种获取下一个序列值的方法: 但是,这种方式会大大降低性能(〜5000个对象的创建速度降低了3倍-从5740ms到13648ms)。 我试图添加一个“假”实体: 但是,该方法也不起作用(返回的所有ID为0)。 有人

  • 问题内容: 我知道SO和网络上都有很多这些问题,但是所有答案都建议使用特定于数据库的信息,因此不适用于我,因为我正在使用的系统需要在不同的数据库上运行。 我发现这个hibernate问题,有人要求使用此功能进行注释。该问题已经解决,表示另一个问题将涉及该功能。第二个问题显然添加了注释以及其他一些注释,但是我找不到有关如何使用这些新注释定义默认列值的文档。 所以我的问题是:有谁知道我该如何定义带注释