Hibernate - Enum vs. Entita rubrika: Programování: Java

2 petrf
položil/-a 19.5.2016

Ahoj všem

Chtěl jsem se zeptat, jak řešíte propojení entity na číselník?
Mám v DB tabulky data a cislenik. Vazbu tvoří sloupce data.ciselnik_kod (int), který je provázán se sloupcem cislenik.kod (int). Tabulka cislenik obsahuje ještě sloupec text (text) a poradi (int).
Všechny hodnoty z číselníku jsou ve třídě CislenikEnum.
Jde mi o to, jak efektivně a "správně" pracovat s entitou Data - CRUD operace v Hibernate.
Máme tři návrhy, jak to řešit, ale nevím, který je nejvhodnější nebo by to měla být kombinace a nebo něco úplně jiného?
Návrh entity Data, Ciselnik a CiselnikEnum:

/* CiselnikEnum je pro všechny příklady stejný */
public enum CiselnikEnum {
  A(1), B(2), C(3);
 
  private final int kod;
 
  private CiselnikEnum(int kod) {
    this.kod = kod;
  }
 
  public int getKod() {
    return kod;
  }
}
  1. @Entity
    @Table(name = "CISELNIK")
    public class Ciselnik {
      @Id
      @Column(name = "KOD")
      private int kod;
     
      @Column(name = "PORADI")
      private int poradi;
     
      @Column(name = "TEXT")
      private String text;
    }
    /************************************/
    @Entity
    @Table(name = "DATA")
    public class Data {
     
      @ManyToOne
      @JoinColumn(name = "CISELNIK_KOD", insertable = false, updatable = false)
      private Ciselnik ciselnik;
     
      // ...
    }
    Podmínka pro výběr dat je select d from Data d join d.ciselnik where d.ciselnik.kod = :kod, kde kod je například hodnota CiselnikEnum.A.getKod(). Zde je enum jen jako pomocná proměnná, která nese hodnotu typu int. Lze vložit jakoukoliv číselnou hodnotu, která nemusí být platná, protože se nepoužije hodnota z číselníku.
  2. @Entity
    @Table(name = "CISELNIK")
    public class Ciselnik {
      @Id
      @Column(name = "KOD")
      private CiselnikEnum kod; // Je zajištěna konverze enum na int a obráceně
     
      @Column(name = "PORADI")
      private int poradi;
     
      @Column(name = "TEXT")
      private String text;
    }
    /************************************/
    @Entity
    @Table(name = "DATA")
    public class Data {
     
      @ManyToOne
      @JoinColumn(name = "CISELNIK_KOD", insertable = false, updatable = false)
      private Ciselnik ciselnik;
     
      // ...
    }
    Podmínka pro výběr dat je select d from Data d join d.ciselnik where d.ciselnik.kod = :kod, kde kod je například hodnota CiselnikEnum.A (bez volání funkce getKod()). Zde je enum již jako typ kontroluje Hibernate, takže bych neměl být schopen vložit do dotazu jinou než ENUM hodnotu.
  3. @Entity
    @Table(name = "CISELNIK")
    public class Ciselnik {
      @Id
      @Column(name = "KOD")
      private int kod;
     
      @Column(name = "PORADI")
      private int poradi;
     
      @Column(name = "TEXT")
      private String text;
    }
    /************************************/
    @Entity
    @Table(name = "DATA")
    public class Data {
     
      @ManyToOne(fetch = FetchType.LAZY)
      @JoinColumn(name = "CISELNIK_KOD", insertable = false, updatable = false)
      private Ciselnik ciselnik;
     
      @Column(name = "CISELNIK_KOD")
      private CiselnikEnum ciselnikKod; // Je zajištěna konverze enum na int a obráceně
     
      // ...
    }
    Podmínka pro výběr dat je select d from Data d where d.ciselnikKod = :kod, kde kod je například hodnota CiselnikEnum.A (bez volání funkce getKod()). Není zde ani potřeba Entity číselník pro běžné operace. Přesto je tam ponechána možnost načíst hodnotu číselníku např. kvůli textu. Zde je enum již jako typ kontroluje Hibernate, dotazy se zjednodušily, ale jsou tam dvě proměnné k jedné hodnotě.
    1. Pokud máte někdo praktickou zkušenost jak na to, budu moc rád za každý příspěvek. Díky Petr
odkaz
Anonym
odpověděl/-a 19.5.2016

Ahoj,

urcite do varianty 1. Mozna a to pouze pokud se ti to chce programovat, tak varianta 2. Urcite ne 3. Je to komplikovane mapovani.

Radek

Komentáře

  • petrf : Přiznám se, že mi nikdo nešlo o to zdali se mi chce či nechce něco programovat, ale o to, jak to udělat správně, protože každá věc které se trochu ošidí se časem vždycky vrátí (osobní zkušenost), proto bych chtěl použít co možná nejvhodnější řešení nebo alespoň zjistit, které řešení je vhodné pro určitý druh úlohy. 19.5.2016
  • kohven : To je právě to kouzlo najít střed mezi prasením a overengineering. Programovat něco navíc, znamená udržovat něco navíc. To "správně" vždy záleží na situaci. 23.5.2016

Pro zobrazení všech 4 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.