Question

I'm using Hibernate and Envers 3.6.10 over Postgresql. I've mapped a OneToMany bidirectional relation using a JoinTable between entities A and B as follows.

Class A:

@Entity
@Audited
public class A {
    // Other stuff

    @OneToMany()
    @Cascade(CascadeType.ALL)
    @LazyCollection(LazyCollectionOption.TRUE)
    @JoinTable(name = "A_B", joinColumns = { @JoinColumn(name = "A_ID") }, inverseJoinColumns = { @JoinColumn(name = "B_ID") }) 
    private Set<B> setOfBs;

    // Getters + Setters + HashCode + Equals
}

Class B:

@Entity
@Audited
public class B {
    // Other stuff

    @ManyToOne(optional=true)
    @LazyCollection(LazyCollectionOption.TRUE)
    @JoinTable(name = "A_B", joinColumns = { @JoinColumn(name = "B_ID") }, inverseJoinColumns = { @JoinColumn(name = "A_ID") })
    private A a;

    // Getters + Setters + HashCode + Equals
}

There's no problem when persisting an A entity with a set of Bs through a save(). Even without setting explicitly the bidirectional relation between B and A. The problem appears when Envers is doing inserts to save the revision in the JoinTable aud table getting this exception:

Hibernate: insert into a_b_AUD (a_id, b_id, REV) values (?, ?, ?)
16:27:38,051 TRACE BasicBinder:70 - binding parameter [1] as [BIGINT] - <null>
16:27:38,051 TRACE BasicBinder:82 - binding parameter [2] as [BIGINT] - 2038
16:27:38,051 TRACE BasicBinder:82 - binding parameter [3] as [INTEGER] - 2039
16:27:38,056  WARN JDBCExceptionReporter:233 - SQL Error: 0, SQLState: 23502
16:27:38,056 ERROR JDBCExceptionReporter:234 - ERROR: null value in column «a_id» violates not null restriction

If I set the full debug mode in Hibernate I can see that Envers 'knows' that Id but is not passing it to the insert. How can I solve this issue? Is the relation correctly mapped? Envers need some special config. to manage this?

Best regards.

Was it helpful?

Solution

That could be a bug in Envers, as it's quite an untypical way to map a relation. In fact, from Hibernate's point of view, these are two unidirectional relations, which by incident are mapped to the same columns.

To have a bidirectional relation you'd need to have "mappedBy" in @OneToMany.

OTHER TIPS

The problem is the generated DDL:

CREATE TABLE public.a_b_aud (
  b_id BIGINT NOT NULL, 
  rev INTEGER NOT NULL, 
  a_id BIGINT NOT NULL, 
  CONSTRAINT a_b_aud_pkey PRIMARY KEY(a_id, rev), 
  CONSTRAINT fk_5689e745b66c4ee2a8822e44079 FOREIGN KEY (b_id, rev)
    REFERENCES public.b_aud(id, rev)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION
    NOT DEFERRABLE, 
  CONSTRAINT fk_b5c868c4f5f34d35bdb7a6c1281 FOREIGN KEY (a_id, rev)
    REFERENCES public.a_aud(id, rev)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION
    NOT DEFERRABLE
) WITHOUT OIDS;

The b_id column should be nullable as Envers expect it to be. Just like the same column in public.a_b table. I believe the problem is limited to the DDL generator.

The A to B OneToOne relationship is bidirectionally optional and A is the owner, that's why b_id can be nullable and why primary key points to PRIMARY KEY(a_id, rev).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top