使用注释映射默认列值

时间:2010-09-12 17:41:06

标签: hibernate annotations default-value oracle9i hibernate-annotations

@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 + "]";
    }

}

如果I DONOT设置其值,我期待为每一行插入值'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")
}

1 个答案:

答案 0 :(得分:2)

  

我期待为每一行插入值'15 -JUL-1980',如果我没有设置它的值。

实际上,即使您因creationTime设置了值,insertable = false也永远不会成为SQL INSERT语句的一部分。

  

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

什么不起作用完全?你能为这个表显示DDL脚本吗?什么DML INSERT语句完全执行? Oracle是否适当地设置了默认值?插入后你不能把它拿回实体吗?什么时候失败?

以防万一,您是否错过Temporal上的creationTime注释?根据JPA 1.0规范:

  

9.1.20时间注释

     

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

我会添加@Temporal(TemporalType.DATE)

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


  

我希望Hibernate在我尝试插入时设置默认值。我展示的表是一个虚拟表,我为测试/学习目的而创建。原始表是遗留表,并且没有设置“DEFAULT”属性。对此感到抱歉。

columnDefinition注释的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节“生命周期回调方法”