Java/Hibernate с использованием интерфейсов над сущностями

Я использую аннотированный Hibernate, и мне интересно, возможно ли следующее.

Мне нужно настроить ряд интерфейсов, представляющих объекты, которые могут быть сохранены, и интерфейс для основного класса базы данных, содержащий несколько операций для сохранения этих объектов (... API для базы данных).

Ниже я должен реализовать эти интерфейсы и сохранить их с помощью Hibernate.

Так что у меня будет, например:

public interface Data {
  public String getSomeString();
  public void setSomeString(String someString);
}

@Entity
public class HbnData implements Data, Serializable {
  @Column(name = "some_string")
  private String someString;

  public String getSomeString() {
    return this.someString;
  }
  public void setSomeString(String someString) {
    this.someString = someString;
  }
}

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

public interface HasData {
  public Data getSomeData();
  public void setSomeData(Data someData);
}

Но когда я реализую класс, я могу следовать интерфейсу, как показано ниже, и получить сообщение об ошибке от Hibernate, говорящее, что он не знает класс «Данные».

@Entity
public class HbnHasData implements HasData, Serializable {
  @OneToOne(cascade = CascadeType.ALL)
  private Data someData;

  public Data getSomeData() {
    return this.someData;
  }

  public void setSomeData(Data someData) {
    this.someData = someData;
  }
}

Простым изменением было бы изменить тип с «Data» на «HbnData», но это, очевидно, нарушило бы реализацию интерфейса и, таким образом, сделало бы абстракцию невозможной.

Может ли кто-нибудь объяснить мне, как реализовать это так, чтобы он работал с Hibernate?


person wen    schedule 09.05.2010    source источник
comment
А какой смысл использовать интерфейсы для сущностей? Какое состояние имеет интерфейс, который необходимо сохранить? Интерфейсы касаются поведения, а не состояния, и я не понимаю, почему вы хотите сохранить интерфейс.   -  person Pascal Thivent    schedule 10.05.2010
comment
Я понимаю это... Намерение состояло в том, чтобы создать абстракцию над инфраструктурой персистентности, чтобы можно было реализовать ее несколько раз, используя разные (или никакие) фреймворки. Приложение, о котором идет речь, было создано абсолютно модульным способом, не зависящим от меня, и мне нужен способ указать, на какие сообщения база данных должна иметь возможность реагировать, и какими свойствами обладают объекты... и так: интерфейсы. Идея состоит в том, что можно реализовать интерфейсы и переключать модули. Однако реализация интерфейсов вызывает некоторые проблемы с Hibernate... и, следовательно, мой вопрос.   -  person wen    schedule 10.05.2010
comment
Какое состояние имеет интерфейс, который необходимо сохранить? Что-нибудь, к чему можно получить доступ через геттеры и сеттеры, определенные интерфейсом?   -  person Greg Brown    schedule 25.07.2018


Ответы (2)


Может быть, OneToOne.targetEntity?:

@OneToOne(targetEntity = HbnData.class, cascade = CascadeType.ALL)
private Data someData;
person Sam Donnelly    schedule 29.09.2010
comment
Спасибо, это было действительно то, что я искал. ^^ - person wen; 02.11.2010
comment
То же самое! Ты мой герой! - person nterry; 10.10.2016
comment
Я не понимаю, как это решает проблему, она по-прежнему ограничена одним типом. Заменить данные на HbnData - это то же самое, нет? - person MilacH; 06.02.2017
comment
@MilacH - это не причина для этого, рефакторинг с этим прост, как изменение аннотации, использование реализации интерфейса привязывает вас к этой реализации и означает, что при ее изменении вы должны изменить ВСЕ код, который зависит от этой ссылки. Это основная причина использования интерфейсов. List всегда предпочтительнее ArrayList по той же причине. - person ; 30.11.2017

Обычно я использую интерфейс Data Access Object или DAO. Используя дженерики Java, я могу написать это только один раз; Hibernate также позволяет написать реализацию только один раз:

package persistence;

import java.io.Serializable;
import java.util.List;

public interface GenericDao<T, K extends Serializable>
{
    T find(K id);
    List<T> find();
    List<T> find(T example);
    List<T> find(String queryName, String [] paramNames, Object [] bindValues);

    K save(T instance);
    void update(T instance);
    void delete(T instance);
}
person duffymo    schedule 10.05.2010