Ecliptica
Ecliptica

Reputation: 830

Skip a column on INSERT with JPA

I have a JPA/EclipseLink model with multiple parameters whose values are set as defaults by the PostgreSQL database. Specifically, I have:

My model looks like this:

import javax.persistence.*;

@Entity
@Table(name="entity")
@NamedQuery(name="Entity.findAll", query="SELECT e from Entity e")
public class Entity {
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;

    @Column(name="created_at")
    private java.sql.Timestamp createdAt;

    // constructor, getters, and setters
}

When I try to insert a row with persist() in javax.persistence.EntityManager, the insertion fails because a NULL value is being set for the created_at column. Rather than inserting NULL, I want to simply not insert anything into that column and allow PostgreSQL to set it to now(). Essentially, I would like to use @GeneratedValue on createdAt, but that annotation is only for primary keys and cannot be used on multiple attributes. Is there another annotation I can use that will accomplish this?

Upvotes: 8

Views: 11221

Answers (3)

Stephen Ni
Stephen Ni

Reputation: 61

You can add @DynamicInsert on your entity class. The insert statement will include null fields when without this annotation. Also, you can add @ DynamicUpdate when executing the update statement.

@Entity
@DynamicInsert
@DynamicUpdate
@Table(name="entity")
@NamedQuery(name="Entity.findAll", query="SELECT e from Entity e")
public class Entity {
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;

    @Column(name="created_at")
    private java.sql.Timestamp createdAt;

    // constructor, getters, and setters
}

Upvotes: 3

Chris
Chris

Reputation: 21145

As mentioned in another answer, JPA providers will set the value on insert if you have it marked as insertable=true (the default). This occurs with many providers even if null as it allows statement reuse.

Just excluding it from the statement though might not be what you want, as to have the value in your entity (and in the cache) will require refreshing. EclipseLink though has @ReturningInsert which allows EclipseLink to update the entity with the value in the database. Unfortunately support is only for Oracle - other databases require use of stored procedures to return run the insert and return the value.

Upvotes: 1

Glenn
Glenn

Reputation: 9150

You may want insertable=false in the Column annotation:

@Column(name="created_at", insertable=false)
private java.sql.Timestamp createdAt;

From: http://docs.oracle.com/javaee/5/api/javax/persistence/Column.html

boolean insertable (Optional) Whether the column is included in SQL INSERT statements generated by the persistence provide

Upvotes: 11

Related Questions