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