Можно ли связывать сущности с помощью интерфейсов в 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 не поддерживается напрямую, и рекомендуется использовать другие подходы, чтобы добиться желаемого функционала.
Добрый день <br/> Важный момент почему вы решили использовать интерфейс для связки сущностей? <br/> Вы например, можете создать абстрактный класс и расширить его классами Dog, Cat и т.д. <br/> Т.е. создаете  абстрактный класс Animal. (Обратите внимание на `@Inheritance` ) <br/> А дальше расширяете этот класс другими классами. Ну и связываете Animal с нужными сущностями <br/> <a href="https://www.baeldung.com/hibernate-inheritance" rel="nofollow">https://www.baeldung.com/hibernate-inheritance</a>
Похожие вопросы