Atypic JPA OneToOne关系

时间:2015-02-20 16:41:05

标签: java jpa

我在使用JPA时遇到了问题。

我需要表格:

-----------------
| TableA        |
|---------------|
| ID: INT       |
| ...           |
| ESTATUS1: INT |
| ESTATUS2: INT |
-----------------

-----------------
| EstatusTags   |
|---------------|
| COD: VARCHAR  |---> COD and VALUE are a concatenated PK
| VALUE: INT    |
| DESC: VARCHAR |
-----------------

EstatusTags是一个表,用于存储成对的对象[VALUE,DESC],给定COD。

在我使用JPA之前,我曾经用这样的方式查询这类数据:

SELECT ID, ESTATUS1, ESTATUS2, E1.DESC DESC1, E2.DESC DESC2
FROM TABLEA A
    INNER JOIN ESTATUSTAGS E1 ON E1.COD = "a_estatus1" 
        AND E1.VALUE = A.ESTATUS1
    INNER JOIN ESTATUSTAGS E2 ON E2.COD = "a_estatus2" 
        AND E2.VALUE = A.ESTATUS2

我尝试使用JPA使用两个实体类对其进行建模:

@Entity
@Table(name = "EstatusTags")
public class EstatusTags implements Serializable {

    @EmbeddedId
    private ValueTagPK id;

    @Column(name="VVA_DESC")
    private String desc;

    @Column(name="VVA_ORDEN")
    private Integer orden;
}

@Entity
@Table(name = "TableA")
public class A implements Serializable {

    @Column(name="ID")
    private String desc;

    @OneToOne(???)
    private EstatusTag estatus1;

    @OneToOne(???)
    private EstatusTag estatus2;
}

我对如何建立关系有很强的疑虑。它可以用注释完成吗?有没有必要使用JPQL来适应这种结构?

我希望有人能帮助我。

非常感谢。

1 个答案:

答案 0 :(得分:0)

问题是您的实体模型与表结构不匹配。 在您的实体模型中,您在AEstatusTag之间存在一对一的关系,而在您的表模型中,您有一个A和多个Estatustag的关系(对于一个value,可能存在多个Etatustags条目)

通过向SQL查询中添加虚拟Acod等内容,您可以解决表cod没有E1.COD = "a_estatus1"列的问题。

您可以做的是将value列的两个属性EstatusTag映射到复合pk,将另一个属性映射到单个属性,方法如下。简单的value可通过属性访问访问,但标记为不可更新,不可插入,也不会使setter成为private
备注:我不知道它是否适用于所有JPA实现 - 使用hibernate 4.3.8进行测试。

@Entity
@Table(name = "EstatusTags" )
@Access(AccessType.FIELD)
public class EstatusTag implements Serializable{


    private @EmbeddedId ValueTagPK id;

    @Column(name="VVA_DESC")
    private String desc;

    @Column(name="VVA_ORDEN")
    private Integer orden;



    @Column(name="value", updatable=false, insertable=false)
    @Access(AccessType.PROPERTY)
    public int getValue() {
        return id.value;
    }

    private void setValue(int value) {
        // only because otherwise hibernate complains about a missing setter.
    }

}

@Entity
@Table(name = "TableA")
public class A implements Serializable{


    @Id
    @Column(name="ID")
    @GeneratedValue(strategy=GenerationType.TABLE)
    private int id;

    @OneToOne()
    @JoinColumn(name="estatus1",referencedColumnName="value")
    public EstatusTag estatus1;

    @OneToOne()
    @JoinColumn(name="estatus2",referencedColumnName="value")
    public EstatusTag estatus2;


}