Java 如何在JPA2中创建映射为实体类的3路或4路多对多关联
我正在使用Spring3.1、Hibernate4.0.1.FINAL和SpringDataJPA1.0.2.RELEASE。假设我在Java 如何在JPA2中创建映射为实体类的3路或4路多对多关联,java,hibernate,jakarta-ee,jpa,spring-data,Java,Hibernate,Jakarta Ee,Jpa,Spring Data,我正在使用Spring3.1、Hibernate4.0.1.FINAL和SpringDataJPA1.0.2.RELEASE。假设我在a类和B类之间有一个多对多,映射为ABMap。我还有另一个介于C类和D类之间的多对多映射为CDMap。 我有一个类ABMapIDannotated@embeddeble @Embeddable public class ABMapID{ private String aID; private String bID; } //... setters an
a类
和B类
之间有一个多对多
,映射为ABMap
。我还有另一个介于C类
和D类
之间的多对多映射为CDMap
。
我有一个类ABMapID
annotated@embeddeble
@Embeddable
public class ABMapID{
private String aID;
private String bID;
}
//... setters and getters
下面是映射本身
@Entity
public class ABMap {
@Id
@AttributeOverrides({
@AttributeOverride(name = "aID", column = @Column(name = "a_id",insertable = false, updatable = false)),
@AttributeOverride(name = "bID", column = @Column(name = "b_id", insertable = false,updatable = false))
})
private ABMapID ID;
@ManyToOne(targetEntity = A.class)
@JoinColumn(name = "a_id",insertable = false,updatable = false)
private A a;
@ManyToOne(targetEntity = B.class)
@JoinColumn(name = "b_id", insertable = false, updatable = false)
private B b;
//.... setters and getters
}
现在,我们想将ABMap
更改为ACDMap
,其中ACDMapID
由aID和CDMapID组成(CDMapID本身由cID组成,dID)。
所以我的新关联id是ACDMapID
@Embeddable
public class ACDMapID {
private String aID;
private CDMapID cdmapID;
}
and the entity is mapped like so
@Entity
public class ACDMap {
@Id
@AttributeOverrides({
@AttributeOverride(name = "aID", column = @Column(name = "a_id",insertable = false, updatable = false)),
@AttributeOverride(name = "cdmapID", column = @Column(name = "dcmap_id", insertable = false,updatable = false))
})
private ACDMapID ID;
}
所以运行这个给我这个错误
原因:org.hibernate.AnnotationException:从ACDMap引用CDMap的外键的列号错误。应该是2
有没有办法做到这一点?我更愿意保留CDMap。你似乎不理解JPA的概念。您不应该以编程方式处理ID,而应该处理对象 您需要基于可嵌入对象中的ID的动态关联。也许这样的构造在普通Hibernate中是可能的,但在JPA中肯定不是
JPA的全部目的是让您处理对象,而不是数据库关系。一旦你开始混合这两个方面,地狱就会爆发,所以JPA的人决定不支持这种混合,我不能责怪他们。我想我应该试一试,以下是结果(没有尝试过,所以这纯粹是理论上的)
@Entity
public class A
{
@Id
private Long id;
@ManyToMany
@JoinTable(name = "A_B", joinColumns={
@JoinColumn(name = "a_id")
}, inverseJoinColumns = {
@JoinColumn(name = "b_id")
})
private Collection<B> collectionOfB;
@ManyToMany
@JoinTable(name = "A_C_D", joinColumns={
@JoinColumn(name ="a_id")
}, inverseJoinColumns = {
@JoinColumn(name = "c_id"),
@JoinColumn(name = "d_id")
})
private Collection<ACD> collectionOfCD;
}
@Entity
public class B
{
@Id
private Long id;
@ManyToMany(mappedBy = "collectionOfB")
private Collection<A> collectionOfA;
}
@Entity
public class C
{
@Id
private Long id;
@ManyToMany
@JoinTable(name = "C_D", joinColumns={
@JoinColumn(name = "c_id")
}, inverseJoinColumns = {
@JoinColumn(name = "d_id")
})
private Collection<D> collectionOfD;
}
@Entity
public class D
{
@Id
private Long id;
@ManyToMany(mappedBy = "collectionOfD")
private Collection<C> collectionOfC;
}
@Entity
@Table(name = "C_D")
public class CD
{
@EmbeddedId
private CDPK key;
@MapsId("cId")
@ManyToOne
private C c;
@MapsId("dId")
@ManyToOne
private D D;
}
@Embeddable
public class CDPK
{
@Column(name = "c_id")
private Long cId;
@Column(name = "d_id")
private Long dId;
}
| A | | A_B | | B |
| id |------<| a_id | b_id |>-----| id |
|
|
| | A_C_D |
\----<| a_id | c_id | d_id |
\/ \/
| |
| |
| C | | C_D | | D |
| id |----<| c_id | d_id |>-----| id |