簡體   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