Ayelet
Ayelet

Reputation: 1743

JPA insertable = false updatable = false id not updated on creation

We have 2 entities with a @ManyToOne relationship.

When we create an instance of EntityB within a @Transactional method, entityAId (insertable = false updatable = false), is not updated automatically - even though that the entityA instance was already persisted.

Is there a way around this? Do we have to update it manually in the ctor?

@Entity
public class EntityA {

    @Id
    @GeneratedValue
    private Long id;

    public EntityA() {
       super();
    }
    ...
}

@Entity
public class EntityB {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne(optional = true, fetch = FetchType.LAZY)
    private EntityA entityA;
    @Column(name = "entityA_id", insertable = false, updatable = false)
    private Long entityAId;    

    public EntityB() {
        super();
    }

    public EntityB(EntityA entityA) {
        super();
        this.entityA = EntityA;
    }
    ...
}

EDIT: Also tried the following, but still entityAId = null within the transaction (even though entityA was persisted before).

@Entity
public class EntityB {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "entityA_id", insertable = false, updatable = false)
    private EntityA entityA;
    @Column(name = "entityA_id")
    private Long entityAId;
   ...
}

Upvotes: 2

Views: 13415

Answers (3)

Dragan Bozanovic
Dragan Bozanovic

Reputation: 23552

Hibernate is not going to populate entity fields 'on the fly' (when you change some other fields or similar). It is also not going to do it on persist/flush (exceptions being some special fields like id and version).

Non-insertable/non-updatable fields are populated when entity instances are fetched from the DB. So, to make such fields initialized/refreshed by Hibernate in the same transaction in which you perform changes to the underlying columns they are mapped to, you should first flush the session and then either:

  1. clear the session and re-read the entities;
  2. or, refresh the entities for which you want to reflect such kind of changes.

Upvotes: 3

M Sach
M Sach

Reputation: 34424

To me your mapping does not look right. @ManyToOne or any other association defined between entities but you have defined it on entityAId. Ideally it should be entity (an here you should use insertable = false updatable = false)and you should have separate field entityAId with @column defined on it. Now you should update this field yourself.

If you want to handle hibernate for you remove insertable = false updatable = false

Upvotes: 0

slartidan
slartidan

Reputation: 21576

To update the id field a persist action of the object is required. By default, objects in field entityA are not automatically persisted when persisting an object of EntityB.

I see two possible solutions:

A) Use cascade

@ManyToOne(optional = true, fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST})
private EntityA entityA;

(or use CascadeType.ALL)

B) Persist entityA manually

entityManager.persist(entityA);

Upvotes: 0

Related Questions