JPA2如何从表A,表C中显示字段如果表A连接表B然后连接表C?

问题描述:

每个主题,我有一个实体A,让我们说列a1(PK),a2。 实体B,与列A2(PK),B1 实体C,与列B1(PK),C1JPA2如何从表A,表C中显示字段如果表A连接表B然后连接表C?

所以加入与A2到B,然后加入到C与B1 (他们都是一个一个关系)

这些实体在webservice中被使用,当被调用时将生成一个包含这些实体列表的XML文件。 现在生成一个包含字段a1,a2,a1的XML合并实体A和B非常简单。

但是,如果我想生成仅显示实体A和实体C的XML,那么所需的语法/注释是什么?我的意思是,我如何设置实体A以便它能够实现?

我也将解决,如果我能得到实体A,B各领域,C.

我使用JPA2,EJB3.1

编辑:添加的例子。

实体A

@Entity 
@Table(name = "TABLE_A") 
@XmlRootElement 
@NamedQueries({ 
    @NamedQuery(name = "MyComplex.findAll", query = "SELECT j FROM MyComplex j"), 
    @NamedQuery(name = "MyComplex.findA1", query = "SELECT j FROM MyComplex j WHERE j.a1 = :A1") 
}) 
public class MyComplex implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Column(name = "A1", length = 1) 
    private String a1; 

    @Column(name = "A2", length = 1) 
    private String a2; 

    public MyComplex() { 
    } 

    public MyComplex(String a1) { 
     this.a1 = a1; 
    } 

    public String getA1() { 
     return a1; 
    } 

    public void setA1(String a1) { 
     this.a1 = a1; 
    } 

    public String getA2() { 
     return a2; 
    } 

    public void setA2(String a2) { 
     this.a2 = a2; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 0; 
     hash += (a1 != null ? a1.hashCode() : 0); 
     return hash; 
    } 

    @Override 
    public boolean equals(Object object) { 
     if (!(object instanceof MyComplex)) { 
      return false; 
     } 
     MyComplex other = (MyComplex) object; 
     if ((this.a1 == null && other.a1 != null) || (this.a1 != null && !this.a1.equals(other.a1))) { 
      return false; 
     } 
     return true; 
    }  
    @Override 
    public String toString() { 
     return "jpa.mypackage.Table_A[a1=" + a1 + " ]"; 
    }  
} 

实体B

@Entity 
@Table(name = "TABLE_B") 
@XmlRootElement 
@NamedQueries({ 
    @NamedQuery(name = "Table_B.findAll", query = "SELECT j FROM Table_B j"), 
    @NamedQuery(name = "Table_B.findA2", query = "SELECT j FROM Table_B j WHERE j.a2 = :A2") 
}) 
public class Table_B implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Column(name = "A2", length = 1) 
    private String a2; 

    @Size(max = 1) 
    @Column(name = "B1", length = 1) 
    private String b1; 

    //entity constructor here 

    //entity get/set methods here 

    //entity hash methods here  
} 

实体Ç

@Entity 
@Table(name = "TABLE_C") 
@XmlRootElement 
@NamedQueries({ 
    @NamedQuery(name = "Table_C.findAll", query = "SELECT j FROM Table_C j"), 
    @NamedQuery(name = "Table_C.findB1", query = "SELECT j FROM Table_C j WHERE j.b1 = :B1") 
}) 
public class Table_C implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Column(name = "B1", length = 1) 
    private String b1; 

    @Size(max = 1) 
    @Column(name = "C1", length = 1) 
    private String c1; 

    //entity constructor here 

    //entity get/set methods here 

    //entity hash methods here  
} 

修改实体A加入实体B

@Entity 
@Table(name = "TABLE_A") 
@XmlRootElement 
@NamedQueries({ 
    @NamedQuery(name = "MyComplex.findAll", query = "SELECT j FROM MyComplex j"), 
    @NamedQuery(name = "MyComplex.findA1", query = "SELECT j FROM MyComplex j WHERE j.a1 = :A1") 
}) 
public class MyComplex implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Column(name = "A1", length = 1) 
    private String a1; 

    @Column(name = "A2", length = 1) 
    private String a2; 

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    @JoinColumn(name="A2", referencedColumnName="A2") 
    private Table_B table_B; 

    //entity constructor here 

    //entity get/set methods here 
    public Table_B getTable_B() { 
     return table_B; 
    } 

    public void setTable_B(Table_B table_B) { 
     this.table_B = table_B; 
    }  

    //entity hash methods here 
} 
+0

没有代码示例很难给出确切的答案。我只能建议你创建一个只包含所需列的包装实体,并填充这个(包装)实体的列表,然后将它提供给web服务 – JScoobyCed 2012-03-07 09:19:40

+0

@JScoobyCed你的意思是创建一个jpa原生查询(通过createNativeQuery),调用它并填充所有字段的包装实体? – codeIsFun 2012-03-08 02:21:51

+0

是的,这是想法 – JScoobyCed 2012-03-08 03:06:40

根据你的身材,我看表-B只是一个连接表A和C.如果您在MyComplex.java设置OneToOne注释与JoinTable,那么我相信你可以设置Table_A和Table_C的关系。

@Entity 
@Table(name = "TABLE_A") 
@XmlRootElement 
@NamedQueries({ 
    @NamedQuery(name = "MyComplex.findAll", query = "SELECT j FROM MyComplex j"), 
    @NamedQuery(name = "MyComplex.findA1", query = "SELECT j FROM MyComplex j WHERE j.a1 = :A1") 
}) 
public class MyComplex implements Serializable { 
/* ------------------------------------ */ 
@OneToOne 
@JoinTable(
     name="Table_B", 
     joinColumns= 
      @JoinColumn(name="A2", referencedColumnName="A2"), 
     inverseJoinColumns= 
      @JoinColumn(name="B1", referencedColumnName="B1") 
    ) 
private Table_C tableC; 
/* ------------ */ 
} 
+0

谢谢,我最初测试了代码,但Netbean/eclipselink抱怨有关引用/映射的东西“不对应映射引用上的有效字段”......我以某种方式将netbean项目以新名称复制并重新部署到glassfish,由于公共内存问题而失败...服务器重启后,我重新部署了该项目,并成功显示了所需的所有信息。我仍然不确定为什么相同的代码最初失败,但最初在服务器重启后成功...... – codeIsFun 2012-03-14 09:26:11

+0

'参考/映射'与映射参考'上的有效字段不对应'?主要是因为丢失或persistences.xml中的无效实体定义 – TinHtun 2012-03-15 08:12:57