Atypic JPA OneToOne关系 [英] Atypic JPA OneToOne relation

查看:65
本文介绍了Atypic JPA OneToOne关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用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是否有必要使用以适合此结构?

我希望有人可以帮我这个忙.

非常感谢.

解决方案

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

通过将诸如虚拟codE1.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆