Díky ale nebude to asi to pravé.

Nejsem si jistý, ale pokud používám HQL, tak se z hlavního selektu naplní pouze entita, která je ve frázi FROM a na definicích EAGER se generují parciální sql příkazy k naplnění referencovaných entit. To není žádoucí. Pomalé pro větší seznam.

Navíc se říká, aby byl sql příkaz optimální, má načítat jen to, co potřebuji.

Podařilo se mi vydedukovat v dokumentaci, jak má být popsaný seznam v selektu.
Takže Select {s.*}, {pd.*}, {t.element.*} from entita en
           join PersDate pd on pd.entita_id=en.id
           left join entita_tariffs ents on .......
           join Tariff t on ....."

generuje příkaz správně bez spojovací tabulky entita_tariffs, bohužel načtení výsledku metodou query.list() havaruje.

SQLQuery query = session.createSQLQuery(cmd)
               .addEntity("en", EntitaImpl.class)
               .addJoin("pd","en.persData")
               .addJoin("t","en.insuredTariffs");
List<Entita> query.list();

metoda .addJoin("t","en.insuredTariffs") nejspíš musí být pro tento případ jinak. Nedaří se mi zjistit, jak to v tomto případě má být.

Má s createSQLQuery někdo zkušenosti?

Děkuji.

Arnošt


Dne 16.11.2012 15:22, Petr Janata napsal(a):
Nevím, jestli to v tomhle konkrétní případě pomůže, ale fetchStrategy
se dá změnit i v jednotlivé query v HQL nebo Criteria API. Možná se
vyhnete psaní native SQL.

HQL: left join fetch x.collection
CriteriaAPI criteria.setFetchMode("collection", FetchMode.JOIN)

Petr

On 16/11/2012, Arnošt Hrdina<hrdina.arn...@elvoris.cz>  wrote:
Vážení,

používám Hibernate a v některých případech jsem se nevyhnul použití
nativní sql.
Aby mi v závislostech LAZY negeneroval hibernate jednotlivé sql příkazy,
což při širším seznamu výsledku představuje neúnosný čas,
napsal jsem nativní sql příkaz, který by měl vše načíst naráz i do
závislých entit i pro entity, které jsou definovány jako LAZY.

Mám ale problém v případě, relace ManyToMany, kdy je závislost definována:

@Entity("entity")
class Entita ... {

      @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST,
CascadeType.MERGE },
                  targetEntity = .... .PersonalDataImpl.class)
      @JoinColumn(name = "`persData`")
      private PersonalData persData;

      @ManyToMany(  fetch = FetchType.LAZY, targetEntity = .....
TariffImpl.class)
      @JoinTable(name = "entita_tariffs",
              joinColumns = {@JoinColumn(name = "entita_id") },
              inverseJoinColumns = @JoinColumn(name = "tariff_id"))
      private List<Tariff>   tariffs;

......

}

Dále použiji nativní select

String cmd =
      "Select {s.*}, {pd.*}, {t.*} from entita en
          join PersDate pd on pd.entita_id=en.id
          left join entita_tariffs ents on .......
          join Tariff t on ....."


A načítám

          Session session = (Session) getEntityManager().getDelegate();

          SQLQuery query = session.createSQLQuery(cmd)
              .addEntity("en", InsuredSubjectImpl.class)
              .addJoin("pd","en.persData")
              .addJoin("t","en.insuredTariffs");

EnttyManager je injektován Springem, ale to nejspíš nemá vliv.
Problém je, že se mi Hibernate tom případě z {t.*}  vygeneruje na
t.entita_tariffs_entita_id, t.entita_tariffs_tariffs_id, t.id, t. ...
další pole z tabulky Tariff.
Jenže t.entita_tariffs... jsou pole z tabulka entita_tariff, která
tabulky spojuje tabulky Entita a Tariff a pochopitelně v tabulce Tariff
neexistuje a havaruje.
Pokud je jednoduchá závislost, jako .addJoin("pd","en.persData"), tak
vše funguje správně.
Nepřišel jsem na způsob, jak to zapsat a příklad mi Dr.Google též
neposkytl.
Neřešil jste prosím pánové tento problém někdo?

Děkuji předem za radu a pomoc.

Arnošt





Odpovedet emailem