开发者

JPA/Hibernate, @OneToMany and constraints (Oracle)

开发者 https://www.devze.com 2023-03-30 15:49 出处:网络
I have the following scenario: @Entity class A { @Id @GeneratedValue private long dbId; @OneToMany ( cascade = CascadeType.ALL )

I have the following scenario:

@Entity
class A {

  @Id
  @GeneratedValue
  private long dbId;

  @OneToMany ( cascade = CascadeType.ALL )
  @JoinColumn( name = "A_ID", referencedColumnName = "DBID" )
  Set<C> setOfCs;

}

@Entity
class B {

  @Id
  @GeneratedValue
  private long dbId;

  @OneToMany ( cascade = CascadeType.ALL )
  @JoinColumn( name = "B_ID", referencedColumnName = "DBID" )
  Set<C> setOfCs;

}

@Entity
class C {

    @Id
@GeneratedValue
private long dbId;

}

Table C is created with two columns A_ID and B_ID as foreign keys to A.DBID and B.DBID respectively. This makes little sense in my case as each element of C is either linked f开发者_Python百科rom A or (xor) B but not both at the same time (both relationships are one-to-many not many-to-many).

Is there a way to have the same tables (which are fine) without the foreign key constraint on A_ID and B_ID? When I set A->C Oracle complains that C.B_ID is not set.

Thanks

Matteo


Why don't you use @JoinTable? it will remove any foreign key on table C.

@OneToMany(cascade = CascadeType.ALL,fetch=FetchType.LAZY,orphanRemoval=true)
@JoinTable(name = "A_B_TABLE", joinColumns = { @JoinColumn(name = "A_ID") },      inverseJoinColumns = { @JoinColumn(name = "DB_ID") })
public Set<C> getSetOfCs() {
    return setOfCs;
}

and by the way do not annotate items, do it on its getters instead.


The only way i can think of to do this is to force both relationships through a common class, to which C can have a foreign key.

The simplest way to do this would be to introduce some class X which would be a superclass of A and B, and would have the dbId and setOfCs properties. C's table would then have a column X_ID.

Alternatively, make C abstract, and introduce subclasses Ca and Cb, such that instances of A always referred to instances of Ca, and instances of B to Cb. Each of Ca and Cb would only need a single foreign key. This might be very awkward to use, though; amongst other things, it would mean you could never transfer an instance of C from an A to a B.

If you weren't in a position to introduce any base classes, you could apply Wheeler's law and plaster on a layer of indirection, combining both the above approaches. Create an abstract class X, and give it the dbId and setOfCs properties from A and B; C then has a phantom ManyToOne relationship to X, and it table has the corresponding foreign key. Create two concrete subclasses of X, Xa and Xb, each having a OneToOne relationship with an instance of A or B respectively, those instances of A and B having corresponding OneToOne relationships pointing in the other direction.

0

精彩评论

暂无评论...
验证码 换一张
取 消