0

I have a JPA entity Foo which can point to one of 2 different entities as parent. This is clarified with @Any/@AnyMetaDef annotations. One other side, the parent entities each point to a @OneToMany List[Foo]. One of the parent entities also happens to point to a single optional instance of the other parent entity.

Here is what they look like:

// Foo

@Any(metaColumn = @Column(name = "parent_type"), optional=false)
@AnyMetaDef(
      metaType = "string",
      idType = "java.util.UUID",
      metaValues = {
              @MetaValue(value = "targetOne", targetEntity = TargetOne.class),
              @MetaValue(value = "targetTwo", targetEntity = TargetTwo.class),
      })
@JoinColumn(name = "parent_id")
private Base parent;

// TargetOne extends Base

@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "parent_id", referencedColumnName = "id", insertable = false, updatable = false)
@OrderBy("index ASC")
private List<Foo> targetOneItems;

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "target_two_id")
private TargetTwo targetTwo;

// TargetTwo extends Base

@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "parent_id", referencedColumnName = "id", insertable = false, updatable = false)
@OrderBy("index ASC")
private List<Foo> targetTwoItems;

When I create instances of TargetOne with some Foo children and targetOne.targetTwo=null things work fine.

When I create an instance of TargetOne with some Foo children, holding a TargetTwo with other Foo children, then the saves seem to work fine but once my logic is done and JPA takes over and tries to actually write to the DB (fake Hibernate test db), I get a constraint violation exception:

org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException:
Referential integrity constraint violation: 
"FKDRL80OAM7VU3AT5TBH94NHE1W: PUBLIC.FOOS FOREIGN KEY(PARENT_ID) REFERENCES PUBLIC.TARGETONES(ID) ('e8ef3354-4e43-4308-b4b7-d002c7504aa3')"; SQL statement:
insert into foos (parent_type, parent_id, ...other columns...) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

(Here e8ef3354-4e43-4308-b4b7-d002c7504aa3 is the TargetTwo ID)

This seems weird because the save()s worked, and inspecting the tree in the debugger it looks fine - all the Foos under the TargetOne point to the TargetOne as parent, and all the Foos under the TargetTwo point to the TargetTwo as parent. So why is it apparently complaining that the TargetTwo's Foos should point to a TargetOne?

NOTE: This question is not the same as the linked "dupe". The stuff in that question already works fine for me. My question is one level deeper. Please unlock.

evilfred
  • 2,314
  • 4
  • 29
  • 44
  • The dupe target is pretty old, but the situation is unchanged as far as I can tell. [The current docs](https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#associations-any) are clearer though: "The `@Any` mapping is useful to emulate a **unidirectional** `@ManyToOne` association" (emphasis added). One of the answers to the dupe target suggests a possible workaround, though it's not quite clear to me why that suggestion would work. – John Bollinger Sep 16 '22 at 19:34
  • I already have a join column like in the dupe response, and the original question is 12 years old without an accepted answer. The use case in that question already works for me. My question goes one level deeper - it includes an object holding items of type A holding an object holding items of type B. Please unlock my question. – evilfred Sep 16 '22 at 19:54
  • The dupe target does have an accepted (and upvoted +5) answer. It says what the Hibernate docs also (still) say: that `@Any` is supported only for unidirectional relationships. I'm sorry if that's not the answer you wanted, but yours is the same question, and that answer seems still to be the correct answer. – John Bollinger Sep 16 '22 at 20:35

0 Answers0