Atypic JPA OneToOne关系 [英] Atypic JPA OneToOne relation
问题描述
我在使用JPA时遇到问题.
我要桌子:
-----------------
| TableA |
|---------------|
| ID: INT |
| ... |
| ESTATUS1: INT |
| ESTATUS2: INT |
-----------------
-----------------
| EstatusTags |
|---------------|
| COD: VARCHAR |---> COD and VALUE are a concatenated PK
| VALUE: INT |
| DESC: VARCHAR |
-----------------
EstatusTags是一个表,用于在给定COD的情况下存储对[VALUE,DESC]对.
在我使用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是否有必要使用以适合此结构?
我希望有人可以帮我这个忙.
非常感谢.
问题是您的实体模型与表结构不匹配.
在您的实体模型中,A
和EstatusTag
之间具有一对一的关系,而在表模型中,您具有一个A和多个Estatustag的关系(对于一个value
,可能存在多个Etatustags条目)>
通过将诸如虚拟cod
列E1.COD = "a_estatus1"
之类的内容添加到SQL查询中,可以解决表A
没有cod
列的问题.
您可以做的是用以下方式将value
列映射到EstatusTag
的两个属性,一次映射到合成pk,另一次映射到单个属性.可通过属性访问来访问简单的value
,但是将其标记为不可更新且不可插入,该设置程序也将无法正常工作,因此将其设置为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;
}
I have a problem using JPA.
I have to tables:
-----------------
| TableA |
|---------------|
| ID: INT |
| ... |
| ESTATUS1: INT |
| ESTATUS2: INT |
-----------------
-----------------
| EstatusTags |
|---------------|
| COD: VARCHAR |---> COD and VALUE are a concatenated PK
| VALUE: INT |
| DESC: VARCHAR |
-----------------
EstatusTags is a table to store sets of pairs [VALUE, DESC], given a COD.
Before I use JPA, I used to query this kind of data in something like this:
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
I'm trying to use JPA to model this using two entity classes:
@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;
}
I have strong doubts in how to model the relations. Can it be done with annotations? There is necesary the JPQL use to fit this structure?
I hope somebody could help me with this.
Thanks a lot.
The problem is that your entity model does not match the table structure.
In your entity model you have a one to one relation ship between A
and EstatusTag
whereas in your table model you have a relationship of one A and multiple Estatustags (for one value
there may exist multiple Etatustags entries)
You overcome the problem that Table A
does not have a cod
column by adding something like a virtual cod
column E1.COD = "a_estatus1"
to your SQL Query.
What you can do is you map the value
column of to two properties of EstatusTag
one time to the composite pk and the other time to a single property in the following way . The simple value
is made accessible via property access but marked as not updatable not insertable also the setter does not really work and is made private
.
Remark: I don't know if that works with all JPA implementations - Tested with 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;
}
这篇关于Atypic JPA OneToOne关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!