views:

166

answers:

2

I want the first to be generated:

@Id
@Column(name = "PRODUCT_ID", unique = true, nullable = false, precision = 12, 
        scale = 0)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "PROD_GEN")
@BusinessKey
public Long getAId() {
    return this.aId;
}

I want the bId to be initially exactly as the aId. One approach is to insert the entity, then get the aId generated by the DB (2nd query) and then update the entity, setting the bId to be equal to aId (3rd query). Is there a way to get the bId to get the same generated value as aId?

Note that afterwards, I want to be able to update bId from my gui.

If the solution is JPA, even better.

A: 

If you use JPA, after inserting the new A the id should be set to the generated value, i tought (maybe it depends on which jpa provider you use), so no 2nd query needed. then set bld to ald value in your DAO?

Redlab
+3  A: 

Choose your poison:

Option #1

you could annotate bId as org.hibernate.annotations.Generated and use a database trigger on insert (I'm assuming the nextval has already been assigned to AID so we'll assign the curval to BID):

CREATE OR REPLACE TRIGGER  "MY_TRIGGER"
  before insert on "MYENTITY"
  for each row 
begin  
  select "MYENTITY_SEQ".curval into :NEW.BID from dual;
end; 

I'm not a big fan of triggers and things that happen behind the scene but this seems to be the easiest option (not the best one for portability though).

Option #2

Create a new entity, persist it, flush the entity manager to get the id assigned, set the aId on bId, merge the entity.

em.getTransaction().begin();
MyEntity e = new MyEntity();
...
em.persist(e);
em.flush();
e.setBId(e.getAId());
em.merge(e);
...
em.getTransaction().commit();

Ugly, but it works.

Option #3

Use callback annotations to set the bId in-memory (until it gets written to the database):

@PostPersist
@PostLoad
public void initialiazeBId() {
    if (this.bId == null) {
        this.bId = aId;
    }
}

This should work if you don't need the id to be written on insert (but in that case, see Option #4).

Option #4

You could actually add some logic in the getter of bId instead of using callbacks:

public Long getBId() {
    if (this.bId == null) {
        return this.aId;
    }
    return this.bId;
}

Again, this will work if you don't need the id to be persisted in the database on insert.

Pascal Thivent
#4 was what i was thinking about too. simple and easy to understand.
bert
@bert I agree, it communicates the intention pretty clearly.
Pascal Thivent