1
@Entity
@Table(name = "J_CNTRY")
public class CountryEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "myTableGenerator")
    @TableGenerator(name = "myTableGenerator", allocationSize = 5, pkColumnName = "pkName", valueColumnName = "pkValue", table = "j_cntry_pk_table")
    private Long id;

    private String country;

    @Generated(GenerationTime.INSERT)
    @Column(name = "CREATION_TIME", columnDefinition = "DATE default '15-JUL-1980'", insertable = false)
    private Date creationTime;

    public CountryEntity() {
    }

    public Long getId() {
        return id;
    }

    public void setId(final Long id) {
        this.id = id;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(final String country) {
        this.country = country;
    }

    public Date getCreationTime() {
        return creationTime;
    }

    @Override
    public String toString() {
        return "Country [id=" + id + ", country=" + country + ", creationTime="
                + creationTime + "]";
    }

}

如果我不设置它的值,我希望为每一行插入值“15-JUL-1980”。

但它没有按预期工作。我在这里做错什么了吗?

由于某些原因,我想在应用程序中设置默认值,而不是在数据库中。

更新

最初我只尝试不使用“insertable = false”。

作为一个新手,我尝试了不同的选择并保留了这个选择。

这是我正在运行的测试用例:

@Test
    public void testCreateCountry4() {
        final CountryEntity a1 = new CountryEntity();
        a1.setCountry("Xxxx");
        final Session currentSession = sessionFactory.getCurrentSession();
        final Long savedId = (Long) currentSession.save(a1);
        System.out.println("Saved with ID = " + savedId);
        currentSession.flush();
        System.out.println("Saved object = " + a1);
        assertNotNull(savedId);
    }

以及它产生的输出:

Saved with ID = 85
Hibernate: 
    /* insert entities.CountryEntity
        */ insert 
        into
            J_CNTRY
            (country, id) 
        values
            (?, ?)
Hibernate: 
    /* get generated state entities.CountryEntity */ select
        countryent_.CREATION_TIME as CREATION3_2_ 
    from
        J_CNTRY countryent_ 
    where
        countryent_.id=?
Saved object = Country [id=85, country=Xxxx, creationTime=null]

桌子:

CREATE TABLE "FOO"."J_CNTRY" 
   (    "ID" VARCHAR2(255 BYTE) NOT NULL, 
    "COUNTRY" VARCHAR2(255 BYTE), 
    "CREATION_TIME" DATE, 
     CONSTRAINT "J_CNTRY_PK" PRIMARY KEY ("ID")
}
4

1 回答 1

2

如果我不设置它的值,我希望为每一行插入值“15-JUL-1980”。

实际上,creationTime即使由于insertable = false.

但它没有按预期工作。我在这里做错什么了吗?

什么不工作?你能显示表格的 DDL 脚本吗?究竟执行了什么 DML INSERT 语句?Oracle 是否适当地设置了默认值?插入后你不把它放回实体中吗?什么时候失败?

以防万一,您不是缺少Temporal注释creationTime吗?根据 JPA 1.0 规范:

9.1.20 时间注释

必须为和类型的持久字段或属性指定 Temporal注释。只能为这些类型的字段或属性指定它。java.util.Datejava.util.Calendar

我会添加一个@Temporal(TemporalType.DATE).

虽然不确定这会解决问题,但回答上述问题可能有助于诊断问题。


我希望 Hibernate 在我尝试插入时设置默认值。我展示的表格是我为测试/学习目的而创建的虚拟表格。原始表是旧表,它没有设置“默认”属性。很抱歉造成混乱。

annotation的columnDefinition元素Column用于指定在为 column 生成 DDL 时使用的 SQL 片段,仅此而已。如果您不使用 JPA 提供程序来生成 DDL,并且您的表没有任何DEFAULT定义,则不会发生任何事情。

因此,在您的情况下,如果在以下情况下,我可能会使用生命周期回调并设置null日期PrePersist

@Entity
public class Account {
    ...

    @PrePersist
    protected void setCreationDateIfRequired() {
        if (getCreationDate() == null) {
            setCreationDate(...);
        }
    }

}

参考

  • JPA 1.0 规范
    • 第 3.5.1 节“生命周期回调方法”
于 2010-09-12T18:42:12.090 回答