Один и только один, общие отношения первичного ключа JPA - PullRequest
0 голосов
/ 11 января 2020

Проблема в следующем: представьте, что у нас есть сущность героя. Из этой сущности героя у нас есть идентификатор (первичный ключ) и имя. Теперь у меня есть еще две сущности, одна для героя типа волшебника и одна для героя типа воина. И логика c для постоянства приходит сюда:

  1. Я не могу сохранить в таблице WizardHero или WarriorHero без предварительного сохранения в таблице Hero.
  2. В таблицах WizardHero и WarriorHero используются первичный ключ таблицы героев.
  3. К тому времени, когда я связываю идентификатор героя с WizardHero, я больше не могу использовать тот же ключ для WarriorHero, и наоборот (ie У меня может быть только один герой связан с одним типом).

Внимание Я считаю, что сущности WizardHero и WarriorHero имеют разные атрибуты. Я уже рассмотрел использование @MappedSuperclass, и когда я пытаюсь установить другие отношения, в приложении возникает неизвестная ошибка сопоставленной сущности. Решение, которое я ищу, состоит в том, как сопоставить все эти сущности и логики c в 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;
}

WizardHero. 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;
}

1 Ответ

0 голосов
/ 12 января 2020

Я думаю, вам следует использовать стратегию TABLE_PER_CLASS.


Я уже рассмотрел использование @MappedSuperclass, и когда я пытаюсь установить другие отношения, приложение неизвестно ошибка сопоставленной сущности.

Вы можете использовать @MappedSuperclass, если вы не сохраните объект базового класса (героя) . Я полагаю, что вы делаете это, и именно поэтому вы получаете Неизвестная сущность ошибка.

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, либо сохраняйте только экземпляры WizardHero и WarriorHero.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...