EclipseLink 如何使用两个@OneToMany 和@ManyToOne 来替换@ManyToMany

Posted

技术标签:

【中文标题】EclipseLink 如何使用两个@OneToMany 和@ManyToOne 来替换@ManyToMany【英文标题】:EclipseLink how to use two @OneToMany and @ManyToOne to replace @ManyToMany 【发布时间】:2012-05-16 06:41:21 【问题描述】:

我是 eclipselink 的新手,正在尝试在 manyTomany 关联表中添加额外的列。

所以我决定使用两个@OneToMany 和@ManyToOne 来替换@ManyToMany 关系。

我已经尝试过以下链接中的休眠方式,但它不起作用。 http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/

有人知道如何在 eclispelink 中构建它吗?

谢谢

--------------只需点击上面的链接并粘贴测试代码 ------------- -

甲方:

@Entity
@Table(name = "SideA")
    public class SideA 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long  id;

    private List<ABAssociation> association = new ArrayList<ABAssociation>();


    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.sideA", cascade=CascadeType.ALL)
    public List<ABAssociation> getAssociation() 
          return this.association;
    

    public void setAssociation(List<ABAssociation> association) 
    this.association = association;
    


SideB:

@Entity
@Table(name = "SideB")
public class SideB 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long  id;


    private List<ABAssociation> association = new ArrayList<ABAssociation>();


    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.sideB", cascade=CascadeType.ALL)
    public List<ABAssociation> getAssociation() 
        return this.association;
    

    public void setAssociation(List<ABAssociation> association) 
        this.association = association;
    


联想:

@Entity
@Table(name = "ABAssociation")
@AssociationOverrides(
   @AssociationOverride(name = "pk.sideA", 
    joinColumns = @JoinColumn(name = "SIDEA_ID")),
   @AssociationOverride(name = "pk.sideB", 
    joinColumns = @JoinColumn(name = "SIDEB_ID")) )
public class ABAssociation 
   private ABAssociationPK pk = new ABAssociationPK();
   @EmbeddedId
   public ABAssociationPK getPk() 
        return pk;
   
   public void setPk(ABAssociationPK pk) 
       this.pk = pk;
   
   @Transient
   public SideA getSideA() 
       return getPk().getSideA();
   
   public void setSideA(SideA sideA) 
       getPk().setSideA(sideA);
   
   @Transient
   public SideB getSideB() 
       return getPk().getSideB();
   
   public void setSideB(SideB sideB) 
       getPk().setSideB(sideB);
    
   private String extracolumn;

ABAssociationPK:

@Embeddable
public class ABAssociationPK implements java.io.Serializable
    private static final long serialVersionUID = -3797694126054440157L;

    private SideA sideA;
    private SideB sideB;
    public ABAssociationPK()

    @ManyToOne
    public SideA getSideA() 
        return sideA;
    

    public void setSideA(SideA sideA) 
        this.sideA = sideA;
    

    @ManyToOne
    public SideB getSideB() 
        return sideB;
    

    public void setSideB(SideB sideB) 
        this.sideB = sideB;
    


例外是:Exception Description: Predeployment of PersistenceUnit [testPU] failed. Internal Exception: Exception [EclipseLink-7298] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ValidationException Exception Description: The mapping [sideA] from the embedded ID class [class com.fuhu.nabisync.resource.model.entity.ABAssociationPK] is an invalid mapping for this class. An embeddable class that is used with an embedded ID specification (attribute [pk] from the source [class com.fuhu.nabisync.resource.model.entity.ABAssociation]) can only contain basic mappings. Either remove the non basic mapping or change the embedded ID specification on the source to be embedded.

【问题讨论】:

什么不起作用?代码?例外? 它的休眠风格...不能应用于 eclipselink:例如 "@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.category") " pk 是关联表的 @embededid .但这在 eclipselink 中不起作用。 什么不起作用?代码?例外?为什么首先在“加入”实体中使用嵌入式 ID? 嗨 Nizet,我已经更新了测试代码和异常混乱,使用链接提供的方法:mkyong.com/hibernate/… 您还可以通过将注释访问类型放在字段和属性上来混合它们。这将导致一些被忽略。确保将所有注释放在字段或属性上,而不是两者上。 【参考方案1】:

信息很清楚:

与嵌入式 ID 规范一起使用的可嵌入类可以 仅包含基本映射。

因此,ABAssociationPK 类中不能有 ManyToOne 关联。

执行此操作的标准 JPA 方法是使用 @MapsId annotation。 javadoc 提供了一个有用的示例。在您的特定情况下,ABAssociationPK 类应该包含两个 long 类型的字段:aIdbId,映射为基本列。

Association 实体应包含关联,并使用@MapsId 注释:

@ManyToOne
@MapsId("aId")
public SideA getSideA() 
    return sideA;


@ManyToOne
@MapsId("bId")
public SideB getSideB() 
    return sideB;

【讨论】:

感谢您的回答,但我用您的指令更改了测试代码,eclipselink 生成 5 个表:ABASSOCIATION、SIDEA、SIDEA_ABASSOCIATION、SIDEB、SIDEB _ABASSOCIATION。这正常吗?我怎样才能删除 SIDEA_ABASSOCIATION 和 SIDEB _ABASSOCIATION 。谢谢 我没有指定多对一关联的映射。只要有 MapsId 注释,就可以根据需要映射它们。 您得到 SIDEA_ABASSOCIATION 和 SIDEB _ABASSOCIATION 因为 SideA->AbAssocation 映射必须缺少 mappedby 规范。如果没有该或其他映射规范,OneToMany 将默认使用连接表,就像 ManyToMany 一样,这些是默认表名。

以上是关于EclipseLink 如何使用两个@OneToMany 和@ManyToOne 来替换@ManyToMany的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 EclipseLink 重新连接丢失的连接?

使用 eclipselink 和 @namedquery 进行错误转换

如何使用 EclipseLink 使 PostgreSQL 与 OSGi 一起工作

JPA - EclipseLink - 如何更改默认模式

Eclipselink:如何在每个捆绑包中获取 EntityManager?

Eclipselink 2.5 使用 Maven 生成元模型