Можно ли связывать сущности с помощью интерфейсов в Spring JPA?

Добрый день! 

У меня есть класс: 
```java
@Entity 
public class AnimalUser { 
    ... 
    @OneToOne 
    private Animal animal; 
    ... 
} 
```
и интерфейс: 
```java
public interface Animal { 
    public Long getId(); 
    public String getName(); 
} 
```
Также у меня есть классы `Dog` и `Cat`, которые реализуют интерфейс `Animal`. 

Хотел бы узнать, возможно ли осуществить связывание классов через интерфейс в Spring JPA? Заранее благодарю за ответ.
  • 13 ноября 2024 г. 7:13
Ответы на вопрос 2
Добрый день!

В Spring JPA вы не сможете напрямую связать сущности через интерфейсы, так как JPA требует, чтобы вы использовали класс-сущность, а не интерфейсы для связи с другими сущностями.

В вашем случае, если вы хотите использовать полиморфизм и связывать `AnimalUser` с классами `Dog` и `Cat`, которые реализуют интерфейс `Animal`, вам нужно придерживаться следующих рекомендаций:

1. **Объявление связи с конкретным типом:** Вместо того, чтобы использовать интерфейс `Animal`, вы можете связать `AnimalUser` с конкретным классом (например, `Dog` или `Cat`). 

2. **Использование `@MappedSuperclass` или `@Inheritance`:** Если классы `Dog` и `Cat` имеют общие поля и методы, вы можете создать базовый класс, который будет являться сущностью, вместо интерфейса. Либо используйте аннотации `@MappedSuperclass` для общего поведения без создания таблицы или `@Inheritance` для создания иерархической структуры таблиц.

3. **Примерос использованием `@Inheritance`:**

```java
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Animal {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    // Getters and Setters
}

@Entity
public class Dog extends Animal {
    // дополнительные поля для собаки
}

@Entity
public class Cat extends Animal {
    // дополнительные поля для кошки
}

@Entity
public class AnimalUser {
    @OneToOne
    private Animal animal;

    // другие поля и методы
}
```

С помощью этого подхода вы сможете создать связи в модели данных, где `animal` в классе `AnimalUser` может ссылаться на любой класс `Animal`, и JPA будет корректно работать с вашими сущностями.

Таким образом, связывание классов через интерфейсы в Spring JPA не поддерживается напрямую, и рекомендуется использовать другие подходы, чтобы добиться желаемого функционала.
Добрый день 
Важный момент почему вы решили использовать интерфейс для связки сущностей?
Вы например, можете создать абстрактный класс и расширить его классами Dog, Cat и т.д.
Т.е. создаете абстрактный класс Animal. (Обратите внимание на `@Inheritance` )
А дальше расширяете этот класс другими классами. Ну и связываете Animal с нужными сущностями
https://www.baeldung.com/hibernate-inheritance
Похожие вопросы