Ці магу я адключыць спячы рэжым па-за транзакцыі, каб пазбегнуць LazyInitializationException

EDIT - I have solved my specific problem with jackson/hibernate using the library https://github.com/FasterXML/jackson-module-hibernate. The solution was not the one I searched for here, but it is equally valid in my situation.

Арыгінальны пытанне:

Нядаўна я натыкнуўся на сумна вядомы org.hibernate.LazyInitializationException пры выкарыстанні Hibernate/Spring/Джэксан. Праблема для мяне адбываецца, калі Джэксан спрабуе серыялізацыя і аб'екта, знаходзіць атрыбут, які гультаяватае непраўдападобна значэнне і шыны для доступу да яго. Я прачытаў шмат пытанняў, паведамленняў і дыскусій з гэтай нагоды, але прапанаванае рашэнне заўсёды, здаецца, варыянт з двух альтэрнатыў

  • Пераканайцеся, што лянівыя атрыбуты загружаюцца да завяршэння транзакцыі.
  • Налада Джэксан ігнараваць атрыбут.

Цікава, ці ёсць іншае рашэнне, бо той факт, што, калі мая служба вяртае аб'ект Hibernate з некаторымі атрыбутамі ня ініцыялізаваны, то я хачу, каб адлюстраваць аб'ект у гэтай манеры. Настройка Джэксана для канкрэтнай мэты, як уяўляецца, стратэгіяй, дзе ўзровень прадстаўлення мае патрэбу ў заблытаным веданні пласта базы дадзеных і які, здаецца, як дрэннае рашэнне.

Тое, як я хацеў бы, каб працаваць ад майго першапачатковага погляду на асновы з'яўляецца тое, што кожны раз, калі аб'ект Hibernate даступны за межамі здзелкі, спячы рэжым не павінен клапаціцца аб аб'екце, і ён павінен дзейнічаць як звычайны POJO. Па сутнасці:

  1. Запусціце транзакцыю
  2. Выканаць аперацыі CRUD на Hibernate кіраваных аб'ектаў.
  3. Завяршэнне здзелкі і, магчыма, вярнуць непраўдападобныя/змененыя аб'екты, якія могуць быць выкарыстаны для чытання/зменены без падзей, якія распаўсюджваюцца ў асноўны базе дадзеных.

Прыклад жаданага паводзінаў:

//Start transaction
MyEntity entity = entityManager.find(primaryKey, MyEntity.class);
entity.getLazyLoadedFooList(); //Load the list from database
//End transaction
entity.getLazyLoadedBarList(); //Return null instead of throw LazyInitializationException

Асноўная ідэя заключаецца ў тым, што прыкладанні маюць уяўленне, абслугоўванне і DAO пласт. DAO пласт занепакоены CRUD аперацый над базай дадзеных. Пласт Service абгортвае метады DAO ў здзелках і вяртае аб'екты Java, якія прадстаўляюць дадзеныя, якія прасілі. Гэтыя аб'екты затым даступныя на ўзроўні прадстаўлення, які пераўтворыць іх , як яны у патрэбны фармат, у гэтым выпадку JSON.

Два пытанні з гэтай нагоды:

  • Ці можа гэта быць зроблена, як я апісаць або ў нейкім падобным чынам?
  • Гэта добрая/дрэнная ідэя?
2
у гэтым выпадку вам неабходна правільна наладзіць сериалайзер Джэксана з дапамогай анатацый. як пытаць сериализатор ня сериализовать непажаданыя поля.
дададзена аўтар Arun P Johny, крыніца
шкада, што я прапусціў гэтую кропку. У гэтым выпадку я думаю, што вы не пашанцавала, таму што Джэксан праца на аснове выкарыстання уласцівасцяў, геттеры/сетары
дададзена аўтар Arun P Johny, крыніца
шкада, што я прапусціў гэтую кропку. У гэтым выпадку я думаю, што вы не пашанцавала, таму што Джэксан праца на аснове выкарыстання уласцівасцяў, геттеры/сетары
дададзена аўтар Arun P Johny, крыніца
шкада, што я прапусціў гэтую кропку. У гэтым выпадку я думаю, што вы не пашанцавала, таму што Джэксан праца на аснове выкарыстання уласцівасцяў, геттеры/сетары
дададзена аўтар Arun P Johny, крыніца
вы карыстаецеся вэб-дадатак? Акрамя таго, што выкарыстоўваецца фреймворк? экс вясна
дададзена аўтар Arun P Johny, крыніца
у гэтым выпадку вам неабходна правільна наладзіць сериалайзер Джэксана з дапамогай анатацый. як пытаць сериализатор ня сериализовать непажаданыя поля.
дададзена аўтар Arun P Johny, крыніца
у гэтым выпадку вам неабходна правільна наладзіць сериалайзер Джэксана з дапамогай анатацый. як пытаць сериализатор ня сериализовать непажаданыя поля.
дададзена аўтар Arun P Johny, крыніца
Гэта не будзе непраўдападобным, калі ён не даступны, ён не будзе рабіць гатовы прынесці. Што яна робіць гэта пратрымаць сесію адкрытай шляхам з запыту
дададзена аўтар Arun P Johny, крыніца
вы карыстаецеся вэб-дадатак? Акрамя таго, што выкарыстоўваецца фреймворк? экс вясна
дададзена аўтар Arun P Johny, крыніца
Вы можаце выкарыстоўваць static.springsource.org/spring/docs/2.5.x/api/org/…
дададзена аўтар Arun P Johny, крыніца
Вы можаце выкарыстоўваць static.springsource.org/spring/docs/2.5.x/api/org/…
дададзена аўтар Arun P Johny, крыніца
Вы можаце выкарыстоўваць static.springsource.org/spring/docs/2.5.x/api/org/…
дададзена аўтар Arun P Johny, крыніца
Гэта не будзе непраўдападобным, калі ён не даступны, ён не будзе рабіць гатовы прынесці. Што яна робіць гэта пратрымаць сесію адкрытай шляхам з запыту
дададзена аўтар Arun P Johny, крыніца
@ArunPJohny Так У цяперашні час я працую над вэб-прыкладанняў з выкарыстаннем Spring MVC
дададзена аўтар Ludwig Magnusson, крыніца
@ArunPJohny Так У цяперашні час я працую над вэб-прыкладанняў з выкарыстаннем Spring MVC
дададзена аўтар Ludwig Magnusson, крыніца
@ArunPJohny Так У цяперашні час я працую над вэб-прыкладанняў з выкарыстаннем Spring MVC
дададзена аўтар Ludwig Magnusson, крыніца
@ArunPJohny Падобна на тое, вы мне прапанавалі два рашэнні, якія я выразна паказана ў маім пытанні, што я ўжо бачыў на розных форумах і што я тлумачу, што я не хачу выкарыстоўваць.
дададзена аўтар Ludwig Magnusson, крыніца
@ArunPJohny Падобна на тое, вы мне прапанавалі два рашэнні, якія я выразна паказана ў маім пытанні, што я ўжо бачыў на розных форумах і што я тлумачу, што я не хачу выкарыстоўваць.
дададзена аўтар Ludwig Magnusson, крыніца
@ArunPJohny Падобна на тое, вы мне прапанавалі два рашэнні, якія я выразна паказана ў маім пытанні, што я ўжо бачыў на розных форумах і што я тлумачу, што я не хачу выкарыстоўваць.
дададзена аўтар Ludwig Magnusson, крыніца
@ArunPJohny б не тое, што выклікае ўсё гультаяватыя атрыбуты, каб быць непраўдападобным? Я не хачу, каб яны былі вынятыя.
дададзена аўтар Ludwig Magnusson, крыніца
@ArunPJohny б не тое, што выклікае ўсё гультаяватыя атрыбуты, каб быць непраўдападобным? Я не хачу, каб яны былі вынятыя.
дададзена аўтар Ludwig Magnusson, крыніца
@ArunPJohny Але яны з'яўляецца даступныя пры Джэксан пераўтворыць аб'ект у JSON. Джэксан звяртаецца ўсе атрыбуты і чытае іх значэнне.
дададзена аўтар Ludwig Magnusson, крыніца
@ArunPJohny Але яны з'яўляецца даступныя пры Джэксан пераўтворыць аб'ект у JSON. Джэксан звяртаецца ўсе атрыбуты і чытае іх значэнне.
дададзена аўтар Ludwig Magnusson, крыніца
@ArunPJohny Але яны з'яўляецца даступныя пры Джэксан пераўтворыць аб'ект у JSON. Джэксан звяртаецца ўсе атрыбуты і чытае іх значэнне.
дададзена аўтар Ludwig Magnusson, крыніца
@ArunPJohny б не тое, што выклікае ўсё гультаяватыя атрыбуты, каб быць непраўдападобным? Я не хачу, каб яны былі вынятыя.
дададзена аўтар Ludwig Magnusson, крыніца

9 адказы

Пасля выбаркі аб'екта, вы можаце адмацаванне , што з спячага рэжыму сесіі.

Вы не будзеце атрымліваць LazyInitializationException пасля гэтага (але лянівыя поля будзе нулявым).

Так ваш наступны прыклад:

   //Start transaction
   MyEntity entity = entityManager.find(primaryKey, MyEntity.class);
   entity.getLazyLoadedFooList(); //Load the list from database
   //End transaction
    entityManager.clear();//detaches the enitities
    entity.getLazyLoadedBarList(); //Return null instead of throw LazyInitializationException
0
дададзена
Я спрабаваў як ясна і падзяліцца. Нічога не дапамагае. Я выкарыстоўваю Hibernate 5.x Што рабіць я няправільна? Так, я хачу, каб атрымаць нуль пры спробе атрымаць доступ да гультаяватаму неинициализированному полі аб'екта.
дададзена аўтар Sergey, крыніца
Так, Hibernate.
дададзена аўтар Ludwig Magnusson, крыніца
Я ўсё яшчэ атрымліваю тую ж памылку. Дакументацыя для метаду яснага кажа: «Ачысціць кантэкст захавання, у выніку чаго ўсе кіраваныя аб'ектаў аддзяляцца Змены асоб, якія ня вымываюцца ў базу дадзеных не будуць захаваны.". Няма згадкі аперацый чытання. Можа быць, што змены ў асобных аб'ектах, ня захоўваецца, але для чытання аперацыі ўсё яшчэ выконваюцца?
дададзена аўтар Ludwig Magnusson, крыніца
Што JPA правайдэр вы карыстаецеся? Hibernate?
дададзена аўтар WeMakeSoftware, крыніца

Пасля выбаркі аб'екта, вы можаце адмацаванне , што з спячага рэжыму сесіі.

Вы не будзеце атрымліваць LazyInitializationException пасля гэтага (але лянівыя поля будзе нулявым).

Так ваш наступны прыклад:

   //Start transaction
   MyEntity entity = entityManager.find(primaryKey, MyEntity.class);
   entity.getLazyLoadedFooList(); //Load the list from database
   //End transaction
    entityManager.clear();//detaches the enitities
    entity.getLazyLoadedBarList(); //Return null instead of throw LazyInitializationException
0
дададзена
Я спрабаваў як ясна і падзяліцца. Нічога не дапамагае. Я выкарыстоўваю Hibernate 5.x Што рабіць я няправільна? Так, я хачу, каб атрымаць нуль пры спробе атрымаць доступ да гультаяватаму неинициализированному полі аб'екта.
дададзена аўтар Sergey, крыніца
Так, Hibernate.
дададзена аўтар Ludwig Magnusson, крыніца
Я ўсё яшчэ атрымліваю тую ж памылку. Дакументацыя для метаду яснага кажа: «Ачысціць кантэкст захавання, у выніку чаго ўсе кіраваныя аб'ектаў аддзяляцца Змены асоб, якія ня вымываюцца ў базу дадзеных не будуць захаваны.". Няма згадкі аперацый чытання. Можа быць, што змены ў асобных аб'ектах, ня захоўваецца, але для чытання аперацыі ўсё яшчэ выконваюцца?
дададзена аўтар Ludwig Magnusson, крыніца
Што JPA правайдэр вы карыстаецеся? Hibernate?
дададзена аўтар WeMakeSoftware, крыніца

Пасля выбаркі аб'екта, вы можаце адмацаванне , што з спячага рэжыму сесіі.

Вы не будзеце атрымліваць LazyInitializationException пасля гэтага (але лянівыя поля будзе нулявым).

Так ваш наступны прыклад:

   //Start transaction
   MyEntity entity = entityManager.find(primaryKey, MyEntity.class);
   entity.getLazyLoadedFooList(); //Load the list from database
   //End transaction
    entityManager.clear();//detaches the enitities
    entity.getLazyLoadedBarList(); //Return null instead of throw LazyInitializationException
0
дададзена
Я спрабаваў як ясна і падзяліцца. Нічога не дапамагае. Я выкарыстоўваю Hibernate 5.x Што рабіць я няправільна? Так, я хачу, каб атрымаць нуль пры спробе атрымаць доступ да гультаяватаму неинициализированному полі аб'екта.
дададзена аўтар Sergey, крыніца
Так, Hibernate.
дададзена аўтар Ludwig Magnusson, крыніца
Я ўсё яшчэ атрымліваю тую ж памылку. Дакументацыя для метаду яснага кажа: «Ачысціць кантэкст захавання, у выніку чаго ўсе кіраваныя аб'ектаў аддзяляцца Змены асоб, якія ня вымываюцца ў базу дадзеных не будуць захаваны.". Няма згадкі аперацый чытання. Можа быць, што змены ў асобных аб'ектах, ня захоўваецца, але для чытання аперацыі ўсё яшчэ выконваюцца?
дададзена аўтар Ludwig Magnusson, крыніца
Што JPA правайдэр вы карыстаецеся? Hibernate?
дададзена аўтар WeMakeSoftware, крыніца

Вы можаце паспрабаваць наступны код, каб змяніць сутнасць з спячага рэжыму аб'екта ў звычайны POJO. Я выкарыстоўваю яго для мэтаў чытання анатацый на класе, якія існуюць у маім кодзе, але не ў спячым проксі.

import org.hibernate.proxy.HibernateProxy;

import org.hibernate.Hibernate;
import org.hibernate.proxy.HibernateProxy;

public class StripHibernateProxy {

   //This function takes the hibernate entity and forces it to be a real java
   //object instead

@SuppressWarnings("unchecked")
public static  T initializeAndUnproxy(T entity) {

            if (entity == null) {
                    throw new NullPointerException("Entity passed for initialization is null");
            }

            Hibernate.initialize(entity);

            if (entity instanceof HibernateProxy) {
                    entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
            }

            return entity;
    }
}
0
дададзена

Вы можаце паспрабаваць наступны код, каб змяніць сутнасць з спячага рэжыму аб'екта ў звычайны POJO. Я выкарыстоўваю яго для мэтаў чытання анатацый на класе, якія існуюць у маім кодзе, але не ў спячым проксі.

import org.hibernate.proxy.HibernateProxy;

import org.hibernate.Hibernate;
import org.hibernate.proxy.HibernateProxy;

public class StripHibernateProxy {

   //This function takes the hibernate entity and forces it to be a real java
   //object instead

@SuppressWarnings("unchecked")
public static  T initializeAndUnproxy(T entity) {

            if (entity == null) {
                    throw new NullPointerException("Entity passed for initialization is null");
            }

            Hibernate.initialize(entity);

            if (entity instanceof HibernateProxy) {
                    entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
            }

            return entity;
    }
}
0
дададзена

Вы можаце паспрабаваць наступны код, каб змяніць сутнасць з спячага рэжыму аб'екта ў звычайны POJO. Я выкарыстоўваю яго для мэтаў чытання анатацый на класе, якія існуюць у маім кодзе, але не ў спячым проксі.

import org.hibernate.proxy.HibernateProxy;

import org.hibernate.Hibernate;
import org.hibernate.proxy.HibernateProxy;

public class StripHibernateProxy {

   //This function takes the hibernate entity and forces it to be a real java
   //object instead

@SuppressWarnings("unchecked")
public static  T initializeAndUnproxy(T entity) {

            if (entity == null) {
                    throw new NullPointerException("Entity passed for initialization is null");
            }

            Hibernate.initialize(entity);

            if (entity instanceof HibernateProxy) {
                    entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
            }

            return entity;
    }
}
0
дададзена

Ці ёсць рэальны адказ на гэтае пытанне? Я быў апантаны з ім на працягу многіх гадоў, і толькі знайшоў некалькі Hack рашэнняў, такіх як Галаад або модуля Джэксана-гибернации. Было б добра, калі спіць рэжым будзе выконваць кантракт POJO і ня кідаць выключэння, па меншай меры, калі ён быў усталяваны, каб зрабіць гэта. Можа быць, нейкі намёк падобны на толькі для чытання адзін.

List list = em.createQuery(q, Customer.class)
            .setParameter("lastName", "Vest")
            .setHint("org.hibernate.readOnly", true)
            .getResultList();
0
дададзена

Ці ёсць рэальны адказ на гэтае пытанне? Я быў апантаны з ім на працягу многіх гадоў, і толькі знайшоў некалькі Hack рашэнняў, такіх як Галаад або модуля Джэксана-гибернации. Было б добра, калі спіць рэжым будзе выконваць кантракт POJO і ня кідаць выключэння, па меншай меры, калі ён быў усталяваны, каб зрабіць гэта. Можа быць, нейкі намёк падобны на толькі для чытання адзін.

List list = em.createQuery(q, Customer.class)
            .setParameter("lastName", "Vest")
            .setHint("org.hibernate.readOnly", true)
            .getResultList();
0
дададзена

Ці ёсць рэальны адказ на гэтае пытанне? Я быў апантаны з ім на працягу многіх гадоў, і толькі знайшоў некалькі Hack рашэнняў, такіх як Галаад або модуля Джэксана-гибернации. Было б добра, калі спіць рэжым будзе выконваць кантракт POJO і ня кідаць выключэння, па меншай меры, калі ён быў усталяваны, каб зрабіць гэта. Можа быць, нейкі намёк падобны на толькі для чытання адзін.

List list = em.createQuery(q, Customer.class)
            .setParameter("lastName", "Vest")
            .setHint("org.hibernate.readOnly", true)
            .getResultList();
0
дададзена