views:

58

answers:

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

}

I'm expecting the value '15-JUL-1980' to be inserted for each row IF I DONOT set its value.

But its not working as expected. Am I doing anything wrong here?

For some reasons, I want to set the default value at the application and Not at the database.

UPDATE:

Initially i tried without 'insertable = false' only.

As a newbie, I was trying different options and had kept that option.

Here is the test case which I'm running:

@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);
    }

and the output it has produced:

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]

Table:

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")
}
+2  A: 

I'm expecting the value '15-JUL-1980' to be inserted for each row IF I DO NOT set its value.

Actually, the creationTime will never be part of the SQL INSERT statement even if you set a value because of the insertable = false.

But its not working as expected. Am I doing anything wrong here?

What is not working exactly? Can you show the DDL script for the table? What DML INSERT statement is performed exactly? Does Oracle set the default appropriately? Don't you get it back in the entity after the insert? When does it fail?

Just in case, aren't you missing a Temporal annotation on the creationTime? According to the JPA 1.0 spec:

9.1.20 Temporal Annotation

The Temporal annotation must be specified for persistent fields or properties of type java.util.Date and java.util.Calendar. It may only be specified for fields or properties of these types.

I would add a @Temporal(TemporalType.DATE).

Not sure this will solve the issue though but answering the above questions might help to diagnose the issue.


I want Hibernate to set the default value when ever I'm trying to insert. The table i've shown is a dummy table which I created for testing/learnig purpose. The Original table is a legacy one and it does not have the 'DEFAULT' attribute set. Sorry about the confusion.

The columnDefinition element of the Column annotation is used to specify the SQL fragment that is used when generating the DDL for the column, that's all. If you don't use the JPA provider to generate the DDL and if your table doesn't have any DEFAULT defined, nothing will happen.

So in your case, I would probably use a lifecyle callback and set the date if null during PrePersist:

@Entity
public class Account {
    ...

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

}

Reference

  • JPA 1.0 Specification
    • Section 3.5.1 "Lifecycle Callback Methods"
Pascal Thivent