views:

156

answers:

3

I use Eclipselink as my JPA provider, how can I make a field auto increment?

A: 

I just want an auto-increment field for 1 entity.

Yes, I get that, this is what you wrote in your question. But it can be interpreted in several ways and repeating the same thing without clarifying doesn't help much :)

So does Pascal's way work or I have to do what Bytecode suggest, query select (max) counter + 1 from MyEntity, to get the next value, then set it to the design field, the persist?

If you want to increment a field per entity record (e.g. a "counter" for Order with id=1, another one for Order with id=2), what I suggested would work.

If you want a behavior similar to a primary key (i.e. an auto-incremented column), it won't. And in that case, standard JPA doesn't offer any particular facility (standard JPA only allows GenereatedValue on Id annotated field). The only way I can think of would be to insert another dedicated entity just to get the primary key from it.


Your exact requirement is unclear but I'm assuming you're talking about a random field, not the primary key. In that case, you could maybe use life cycle callbacks methods:

@Entity
public class MyEntity {
    ...
    private int counter;
    ...

    @PrePersist
    @PreUpdate
    protected void increment() {
         counter = counter + 1;
    }
}
Pascal Thivent
U are right. It is not a primary key
Harry Pham
I guess this ain't gonna work. For new entities persisted into the DB it always sets their counter field to 1, not `select max(counter) + 1 from MyEntityTbl`. Having said that the OP's question is not very clear...
Bytecode Ninja
@Bytecode You're right, this doesn't give you a `select max(counter) + 1`. But I don't know if this is what the OP wants exactly.
Pascal Thivent
@Bytecode, Pascal: I just want an auto-increment field for 1 entity, and I end up setting it from the database side, instead of via JPA. However, I do want to learn how to set it via JPA. So does Pascal's way work or I have to do what Bytecode suggest, query `select (max) counter + 1 from MyEntity`, to get the next value, then set it to the design field, the persist?
Harry Pham
@Harry I think that @Bytecode's comment was more an observation of the incorrectness than a solution. I don't see how you can implement a `select max(counter) + 1 from MyEntity` in a concurrent environment.
Pascal Thivent
thank you. it make sense. I think this is what `bytecode` want to say as well, [quote from bytecode] `@Harry: unfortunately it looks like that EclipseLink cannot make non-ID fields auto-incremented`. Thank you
Harry Pham
@Harry It's just not part of JPA.
Pascal Thivent
A: 

Some JPA impls allow you to set GeneratedValue on the field whether it is PK or not

+1  A: 

@Harry: unfortunately it looks like that EclipseLink cannot make non-ID fields auto-incremented. But looks like OpenJPA does have this feature:

OpenJPA allows you to use the GeneratedValue annotation on any field, not just identity fields. Before using the IDENTITY generation strategy, however, read Section 3.4, “ Autoassign / Identity Strategy Caveats ” in the Reference Guide.

Bytecode Ninja
Thank you very much
Harry Pham