【问题标题】:JPA eclipselink Inheritance between entities : oracle databaseJPA eclipselink 实体间继承:oracle数据库
【发布时间】:2015-05-29 19:36:34
【问题描述】:

我的 web 应用程序在 vaadin 中遇到了一个小问题,我正在使用 jpa 和 eclipselink 进行映射。我有三个实体:

                    encaiss (@MappedSuperclass contains just Id)
                       |
                       |
                  Encaissement (it contains the main and common properties)
                     /              \
                    /                \
   Encaissement_Technique          Encaissement_espece

当我创建一个以“Espece”为类型的实体“Encaissement”时,它在 Encaissement 表中创建得很好,但它在 Encaissement_espece 表中不存在。

我想我应该根据 @MappedSuperclass 类中的标识符 (ID) 加入这两个表。对于管理我的下属类(即 Encaissement_Technique 和 Encaissement_espece),我将不胜感激,因为我的下一步是从一个简单的表单向这两个表中添加记录(所以如果我有一个字段“libelle”,它存在于 Encaissement 但不在 Encaissement_Espece 中怎么能做出这样的指令:

Encaissement_Espece  espece= new Encaissement_Espece();
espece.setLibelle(field.getValue().toString()); 

这些是我的实体:

encaiss,这个类只包含所有类的 ID

@MappedSuperclass
public abstract class encaiss {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO, generator="encaiss_seq_gen")
    @SequenceGenerator(name="encaiss_seq_gen", sequenceName="ENCAISSEMENT_SEQ", allocationSize = 1, initialValue = 1)
    protected Integer id_encaissement;

    public Integer getId_encaissement() {
        return id_encaissement;
    }

    public void setId_encaissement(Integer id_encaissement) {
        this.id_encaissement = id_encaissement;
    }
}

Encaissement(扩展 encaiss 只是为了拥有一个 Id)

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="ENCAISS_TYPE")
@Table(name="ENCAISSEMENT")
public class Encaissement extends encaiss implements Serializable{

    @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_CLIENT")
    private Client Client;
@Column(name="ENCAISS_TYPE")
    protected String encaiss_type;
    @Column(name="LIBELLE")
    protected String libelle;
    @Column(name="PIECE_JOINTE")
    protected String piece_jointe;
    @Embedded
    protected Avis_Recette avis_recette;

    public Encaissement(String encaiss_type, String libelle, String piece_jointe){
        this.encaiss_type=encaiss_type;
        this.libelle=libelle;
        this.piece_jointe=piece_jointe;
    }

    public Encaissement(){

    }

}

Encaissement_Espece,继承自 Encaissement

@Entity
@DiscriminatorValue("Espece")
@Table(name="ENCAISSEMENT_ESPECE")
public class Encaissement_Espece extends Encaissement{

    public Caisse getCaisse() {
        return caisse;
    }

    public void setCaisse(Caisse caisse) {
        this.caisse = caisse;
    }

    public float getMontant() {
        return montant;
    }

    public void setMontant(float montant) {
        this.montant = montant;
    }

    @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_CAISSE")
    private Caisse caisse;

    @Column(name = "MONTANT")
    private float montant;

    public Encaissement_Espece(float montant){
        this.montant=montant;
    }

    public Encaissement_Espece(){

    }

}

Encaissement_Technique,继承自 Encaissement

@Entity
@DiscriminatorValue("Technique")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="ENCAISS_TECHNIQUE_TYPE")
@Table(name="ENCAISSEMENT_TECHNIQUE")
public class Encaissement_Technique extends Encaissement implements Serializable{

    public Banque getBanque() {
        return banque;
    }

    public void setBanque(Banque banque) {
        this.banque = banque;
    }

    public float getPrimeCoass() {
        return primeCoass;
    }

    public void setPrimeCoass(float primeCoass) {
        this.primeCoass = primeCoass;
    }
    public Set<Periode> getPeriode() {
        return periode;
    }

    public void setPeriode(Set<Periode> periode) {
        this.periode = periode;
    }

    public String getEncaiss_technique_type() {
        return encaiss_technique_type;
    }

    public void setEncaiss_technique_type(String encaiss_technique_type) {
        this.encaiss_technique_type = encaiss_technique_type;
    }
@Column(name="PRIMECOASS")
    protected float primeCoass;
    @Column(name="ENCAISS_TECHNIQUE_TYPE")
    protected String encaiss_technique_type;

    public Encaissement_Technique(float primeCoass, String encaiss_technique_type){
        this.primeCoass=primeCoass;
        this.encaiss_technique_type=encaiss_technique_type;
    }

    public Encaissement_Technique(){

    }

}

我希望我能找到一个相关的答案,因为我徒劳地搜索了这个。对我有很大帮助。

谢谢。

【问题讨论】:

    标签: java oracle jpa eclipselink jpa-2.0


    【解决方案1】:

    “当我以“Espece”作为类型创建实体“Encaissement”时,它在表 Encaissement 中创建良好,但在表 Encaissement_espece 中不存在。”此语句表明您有一个 Encaissement 实例,并期望 JPA 只需更改 encaiss_type 值即可将其转换为 Encaissement_Espece 实例。 Java 对象继承不能以这种方式工作,这就是 JPA 继承试图映射到关系数据库的方式。 java中的对象不能简单地通过设置一个标志来改变它的本质——如果你想要以不同的方式表示数据,你需要创建一个新实例。

    在这种情况下,您需要创建 Encaissement_Espece 类的实例。因为这个类映射到 Encaissement 和 Encaissement_espece 表,所以 JPA 会自动在这两个表中插入一行来表示这个对象。当您创建 Encaissement 实例时,一行进入 Encaissement 表,而当您创建 Encaissement_Technique 实例时,一行进入 Encaissement_Technique 和 Encaissement 表。如果您希望在持久化后更改对象的类型,则需要删除旧实例,刷新,然后持久化新实例。

    正如另一个答案中提到的, encaiss_type 是通过类类型本身控制的,因此不需要映射。拥有一个可能对查询或访问很方便(尽管您可以只使用 etc 的实例);应将其标记为 insertable=false, updatable=false,以免您尝试直接修改该值。

    【讨论】:

    • 嗯,我发现您的回答非常清楚、中肯且有道理。感谢您分享您的知识。
    • 嗨@Chris,你能帮我解决这个问题吗,它与你回答的问题有关:stackoverflow.com/questions/29372233/… 因为这个问题,我无法完成我的工作,我非常感谢你帮助。谢谢
    【解决方案2】:

    删除

    @Column(name="ENCAISS_TYPE")
    protected String encaiss_type;
    

    来自Encaissment。

    它将由 JPA 自动处理。它应该可以解决问题。

    【讨论】:

    • 感谢您的评论,这是答案的一部分。克里斯给出了完整的答案。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 2014-04-20
    • 2011-01-01
    相关资源
    最近更新 更多