我在使用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来适应这种结构?
我希望有人能帮助我。
非常感谢。
答案 0 :(得分:0)
问题是您的实体模型与表结构不匹配。
在您的实体模型中,您在A
和EstatusTag
之间存在一对一的关系,而在您的表模型中,您有一个A和多个Estatustag的关系(对于一个value
,可能存在多个Etatustags条目)
通过向SQL查询中添加虚拟A
列cod
等内容,您可以解决表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;
}