简体   繁体   中英

Jpa 2.0 and Unique Constraints

I'm in a project which is based on Oracle DB and EclipseLink as EM implementation.

I got a table which has a standard id sequence generator, let's say:

@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "INVOICE")
@TableGenerator(name = "INVOICE", allocationSize = 1, table = Constants.SEQUENCE_TABLE, schema = Constants.DATABASE_SCHEMA)
@Column(length = 40)
private String id;

I also got a unique numeric field. I've decided to create a special sequence for that field, and populate it through a trigger, which increments that numeric field on every insert, passing sequence "NextVal".

My question is: is it a good practice to take advantage of @Sequencegenerator and @TableGenerator annotation also for a field that is not an @Id for the same entity ?

I'm not a trigger fan...so adding a thing like this from the hypothetical first snippet... i could manage whole entity with JPA standard Annotations:

@GeneratedValue(strategy = GenerationType.TABLE, generator = "UNIQUEFIELD")
@TableGenerator(name = "UNIQUEFIELD", allocationSize = 1)
@Column
private String uniqueValuesField;

Thanks!

To mark a property as generated, use The Hibernate specific @Generated annotation.Properties marked as generated must additionally be non-insertable and non-updateable. Only @Version and @Basic types can be marked as generated. http://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#mapping-generated

never (the default) the given property value is not generated within the database.

insert the given property value is generated on insert, but is not regenerated on subsequent updates. Properties like creationTimestamp fall into this category.

always the property value is generated both on insert and on update.

hope this can help you.

I think writing a trigger is a redundant action, and it will reduce the readability of the code. There are three main types of ID generators provided in hibernate TABLE, SEQUENCE and IDENTITY.

here is a good read with examples by Vladmihalcea on the Sequence generator strategies provided.

Or else you can create your own sequence generator where I had to keep a unique id among two tables so I did this

@Id
@GenericGenerator(name = "sequence", strategy = "IdGenerator")
@GeneratedValue(generator = "sequence")
@Column(name = "ID", columnDefinition = "BIGINT")

and in the Id generator

Public class IdGenerator extends IncrementGenerator {

private static long nextVal = Long.MIN_VALUE;
private static Object idlock = new Object();
private static volatile String COLUMN_NAME = "id";

@Override
public Serializable generate(SessionImplementor session, Object obj) {
    if (obj == null) {
        throw new HibernateException("Null object passed");
    }
    synchronized (idlock) {
                nextVal = //get the value according to your logic
    }
    return nextVal;
  }

}

JPA does not support sequences on non-id fields, so this isn't likely to work without relying or delving into your provider's native support.

You can always refresh the entity afterward if required to get the values set by triggers, but they are a common enough occurrence on legacy systems, so providers will have support of some form for triggers. EclipseLink has @ReturnInsert and @ReturnUpdate to allow getting the values back from triggers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM