繁体   English   中英

One and Only One,共享主键 JPA 关系

[英]One and Only One, shared Primary Key JPA relationship

问题是这样的:想象一下我们有一个英雄实体。 从这个英雄实体我们有一个 id(主键)和一个名字。 现在我多了两个实体,一个是巫师类型的英雄,一个是战士类型的英雄。 持久化的逻辑就在这里:

  1. 如果不首先坚持在 Hero 表中,我就无法坚持在 WizardHero 或 WarriorHero 表中。
  2. WizardHero 和 WarriorHero 表使用 Hero 表的主键。
  3. 当我将 Hero id 与 WizardHero 相关联时,我不能再为 WarriorHero 使用相同的键,反之亦然(即我只能将一个英雄与一种类型相关联)。

注意我正在考虑 WizardHero 和 WarriorHero 实体具有不同的属性。 我已经考虑使用@MappedSuperclass ,当我尝试建立其他关系时,应用程序出现未知映射实体错误。 我正在寻找的解决方案是如何将所有这些实体和逻辑映射到 JPA?

图表在这里

英雄.java

import java.io.Serializable;
import java.time.LocalDateTime;

import javax.persistence.*;

import org.hibernate.annotations.UpdateTimestamp;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name="hero")
@NamedQuery(name="Hero.findAll", query="SELECT h FROM Hero h")
public class Hero implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(unique=true, nullable=false)
    private Long idHero;

    @UpdateTimestamp
    @Column(name="modification_date", nullable=false)
    private LocalDateTime modificationDate;

    @Column(nullable=false, length=255)
    private String name;
}

巫师英雄.java

import java.io.Serializable;
import java.time.LocalDateTime;

import javax.persistence.*;

import org.hibernate.annotations.UpdateTimestamp;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
@PrimaryKeyJoinColumn(name = "idHero")
@Table(name="wizard_hero")
@NamedQuery(name="WizardHero.findAll", query="SELECT w FROM WizardHero w")
public class WizardHero extends Hero implements Serializable {
    private static final long serialVersionUID = 1L;

    @UpdateTimestamp
    @Column(name="modification_date", nullable=false)
    private LocalDateTime modificationDate;

    @Column(name = "healing_power", nullable=false)
    private short healingPower;
}

我认为你应该使用TABLE_PER_CLASS策略。


我已经考虑使用@MappedSuperclass,当我尝试建立其他关系时,应用程序出现未知映射实体错误。

您可以使用@MappedSuperclass ,前提是您不保留 base-class's(Hero) object 我相信您正在这样做,这就是您收到未知实体错误的原因。

Hero hero = new Hero();
hero.setIdHero(1);
hero.setName("name");

WizardHero wizardHero = new WizardHero();
//set wizardHero properties
WarriorHero warriorHero = new WarriorHero();
//set WarriorHero properties

Session session; //get the session
Transaction transaction = session.beginTransaction();

//for strategy @MappedSuperclass will throw -org.hibernate.MappingException: Unknown entity: Hero 
session.save(hero);

session.save(wizardHero);
session.save(warriorHero);

transaction.commit();
session.close();

所以要么使用TABLE_PER_CLASS ,要么只保留WizardHeroWarriorHero的实例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM