JPA Наследование - PullRequest
       10

JPA Наследование

3 голосов
/ 07 мая 2011

Привет, я новичок в JPA, и мне трудно понять, как он обрабатывает наследование.

У меня есть конкретная проблема, которую мне нужно решить без изменения схемы БД, но если вы не можете найти решение, я был бы признателен за предложения по решению с другой схемой БД (приветствуются решения Hibernate / TopLink).

Если мне было неясно или вам нужна дополнительная информация, пожалуйста, сообщите мне об этом. Заранее спасибо!

У меня есть эта база данных:

TABLE Fruit
Id Varchar (10) Primary Key
size Varchar (10)
fruit_type Varchar(10)

TABLE Apple
Id Varchar (10) Primary Key Foreign Key references Fruit.Id
Apple_Property Varchar(10)

Пока мои сущности выглядят так:

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="fruit_type", discriminatorType=DiscriminatorType.Char)
@DiscriminatorValue(value="fruit")

public class Fruit implements Serializable {

    @Id
    protected String Id;

    protected String size;
}

@Entity
@DiscriminatorValue(value="apple")
//@PrimaryKeyJoinColumn(name="Id" , referencedColumnName="Id")

public class Apple extends Fruit implements Serializable {

    private String Apple_Property;
}

В настоящее время я могу сохранять объекты Fruit без проблем. Объекты Apple сохраняются, только если их объект Fruit еще не сохранен.

Если я пытаюсь сохранить объект Apple с уже сохраненным объектом Fruit:

Fruit fruit1 = new Fruit("1", "Small");
Apple apple1 = new Apple(fruit1, "red");
provider.create(fruit1);
provider.create(apple1);

Я получу сообщение об ошибке, поскольку JPA пытается создать новую строку в таблице Fruit с Id = "1" который уже существует.

..

Ответы [ 4 ]

3 голосов
/ 07 мая 2011

При использовании JPA для сохранения дочернего объекта (т. Е. provider.create(apple1) в вашем случае) запись будет вставлена ​​в дочернюю таблицу и все ее родительские таблицы.Поэтому provider.create(apple1) вставит запись в Fruit и запись в таблицу Apple.

В вашем примере, если вы хотите сохранить объект Apple, достаточно просто вызвать provider.create(apple1).Он также сохранит ссылку на фрукт внутри объекта apple.

Кстати, я предлагаю PK таблицы фруктов в качестве числового типа и использую @GeneratedValue для пометки поля идентификатора бина Fruit.Таким образом, вы можете позволить базе данных генерировать для вас идентификатор, и вам больше не нужно задавать его явно в коде Java, чтобы избежать этой ошибки «ID уже существует» из-за установки уже существующего идентификатора в коде Java.*

1 голос
/ 07 мая 2011

Я думаю, что это работает точно так, как задумано. Когда вы используете объединенное наследование и сохраняете объект apple, JPA автоматически вставит таблицы apple и fruit. Вам не нужно моделировать дополнительное отношение или JoinColumn в ваших классах сущностей.

0 голосов
/ 22 июня 2016

У меня та же проблема, и до сих пор я нашел только один способ - запросить родителя и создать дочерний с родителем. Затем удалите родительский и создайте заново обе записи.

0 голосов
/ 07 мая 2011

Вы пытаетесь использовать концепцию наследования Java при создании таблиц БД, что в этом случае несколько невозможно.Я мог бы придумать другой подход к этой проблеме.Есть стол fruit_type и фрукты.fruit_type (id, typename, desc) fruit (id, name, type_id, desc) здесь type_id будет внешним ключом.

...