Подтвердить что ты не робот

Персистентная коллекция интерфейса с использованием Hibernate

Я хочу сохранить свой литтовый зоопарк в Hibernate:

@Entity
@Table(name = "zoo") 
public class Zoo {
    @OneToMany
    private Set<Animal> animals = new HashSet<Animal>();
}

// Just a marker interface
public interface Animal {
}

@Entity
@Table(name = "dog")
public class Dog implements Animal {
    // ID and other properties
}

@Entity
@Table(name = "cat")
public class Cat implements Animal {
    // ID and other properties
}

Когда я пытаюсь сохранить зоопарк, Hibernate жалуется:

Use of @OneToMany or @ManyToMany targeting an unmapped class: blubb.Zoo.animals[blubb.Animal]

Я знаю о targetEntity -property @OneToMany, но это означало бы, что в моем зоопарке могут жить только собаки или кошки.

Есть ли способ сохранить коллекцию интерфейса, который имеет несколько реализаций, с Hibernate?

4b9b3361

Ответ 1

Аннотации JPA не поддерживаются на интерфейсах. Из Java Persistence with Hibernate (стр .210):

Обратите внимание, что спецификация JPA не поддерживает аннотацию отображения по интерфейсу! Это будет разрешено в будущей версии Спецификация; когда вы читаете это книги, возможно, это будет возможно с аннотациями Hibernate.

Возможным решением было бы использовать абстрактный объект с стратегией наследования TABLE_PER_CLASS (потому что вы не можете использовать сопоставленный суперкласс, который не является сущностью - в ассоциациях). Что-то вроде этого:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractAnimal {
    @Id @GeneratedValue(strategy = GenerationType.TABLE)
    private Long id;
    ...
}

@Entity
public class Lion extends AbstractAnimal implements Animal {
    ...
}

@Entity
public class Tiger extends AbstractAnimal implements Animal {
    ...
}

@Entity
public class Zoo {
    @Id @GeneratedValue
    private Long id;

    @OneToMany(targetEntity = AbstractAnimal.class)
    private Set<Animal> animals = new HashSet<Animal>();

    ...
}

Но нет никакого преимущества в сохранении интерфейса IMO (и, на самом деле, я считаю, что стойкие классы должны быть конкретными).

Ссылки

Ответ 2

Я могу догадаться, что вы хотите отобразить дерево наследования. @Наследование аннотации - это путь. Я не знаю, будет ли он работать с интерфейсами, но он определенно будет работать с абстрактными классами.

Ответ 3

Я думаю, что вам нужно также аннотировать интерфейс с помощью @Entity, и мы должны аннотировать @Transient на всех геттерах и сеттерах интерфейса.