Hibernate 4: LazyInitializationException для выражения EL - PullRequest
2 голосов
/ 03 февраля 2012

У меня есть следующее наследование сущности, давайте начнем с корня (это просто таблица с автоматическим приращением целочисленного идентификатора):

@Entity
@Table(name = "Contacts")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING)
public abstract class Contact implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    protected Integer id;

    ...
}

OrganizationalUnit - это просто имя плюс унаследованный идентификатор:

@Entity
@Table(name = "OrganizationalUnits")
public abstract class OrganizationalUnit extends Contact
{
    @Column
    protected String name;

    ...
}

Organization - это просто пустая сущность (для ссылки):

@Entity
@Table(name = "Organizations")
public abstract class Organization extends OrganizationalUnit
{
    ...
}

Последнее, но не менее важное:

@Entity
@Table(name = "Companies")
@DiscriminatorValue(value = "company")
public class Company extends Organization
{
    @Basic(optional = false)
    @Column(name = "dnd_type")
    private String dndType;

    ...
}

Это дает компании 3 столбца / поля: идентификатор, имя и тип dnd.

На каждую компанию ссылаются из сущности документа в системе (каждый документ имеет компанию-владельца):

@Entity
@Table(name = "Documents")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING)
public abstract class Document implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    protected Integer id;

    @Basic(optional = false)
    @Column(name = "file_name")
    protected String fileName;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "company_id", referencedColumnName = "id")
    protected Company company;

    ...
}

Обратите внимание на @ManyToOne(fetch = FetchType.LAZY, optional = false) в отношениях компании. Обязательно, чтобы здесь не было LAZY, используйте EAGER fetch type здесь. ИСПРАВЛЯЕТ проблему, о которой я говорю здесь (, но я хочу, чтобы она работала с LAZY, также потому что я использую генератор кода для генерации классов сущностей ... и он должен работать! )

Я ссылаюсь Company dndType для каждого документа на странице JSF pq-edit.xhtml , например:

<ui:include src="/subviews/repo-filename-dnd-panel.xhtml">
  <ui:param name="document" value="#{doc}" />
  <ui:param name="documentFileName" value="#{doc.fileName}" />
  <ui:param name="documentCompanyName" value="#{doc.company.name}" />
  <ui:param name="documentCompanyDndSuffix" value="#{doc.company.dndType}" /> <!-- EXCEPTION HERE -->
</ui:include>

Они просто передаются в подпредставление /subviews/repo-filename-dnd-panel.xhtml, где я просто ссылаюсь на параметры, например, documentCompanyDndSuffix, для построения некоторого HTML.

То, что я получаю за #{doc.company.dndType} сейчас:

13:53:56,043 SEVERE [org.richfaces.log.Context] (http--127.0.0.1-8080-3) /subviews/repo-filename-dnd-panel.xhtml @14,63 type="doc-#{documentCompanyDndSuffix}": /pq-edit.xhtml @139,94 value="#{doc.company.dndType}": org.hibernate.LazyInitializationException: could not initialize proxy - no Session: javax.el.ELException: /subviews/repo-filename-dnd-panel.xhtml @14,63 type="doc-#{documentCompanyDndSuffix}": /pq-edit.xhtml @139,94 value="#{doc.company.dndType}": org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194) [jboss-jsf-api_2.1_spec-2.0.0.Beta1.jar:2.0.0.Beta1]
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182) [jboss-jsf-api_2.1_spec-2.0.0.Beta1.jar:2.0.0.Beta1]
    at org.richfaces.component.UIDragSource.getType(UIDragSource.java:95) [richfaces-components-ui-4.1.0.Final.jar:]
    at org.richfaces.renderkit.DragSourceRenderer.getOptions(DragSourceRenderer.java:55) [richfaces-components-ui-4.1.0.Final.jar:]
    at org.richfaces.renderkit.DnDRenderBase.buildClientScript(DnDRenderBase.java:66) [richfaces-components-ui-4.1.0.Final.jar:]
    at org.richfaces.renderkit.DnDRenderBase.buildAndStoreScript(DnDRenderBase.java:43) [richfaces-components-ui-4.1.0.Final.jar:]
    at org.richfaces.renderkit.DnDRenderBase.doEncodeEnd(DnDRenderBase.java:74) [richfaces-components-ui-4.1.0.Final.jar:]
    at org.richfaces.renderkit.RendererBase.encodeEnd(RendererBase.java:175) [richfaces-components-ui-4.1.0.Final.jar:]
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875) [jboss-jsf-api_2.1_spec-2.0.0.Beta1.jar:2.0.0.Beta1]
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1763) [jboss-jsf-api_2.1_spec-2.0.0.Beta1.jar:2.0.0.Beta1]
    at org.richfaces.renderkit.RendererBase.renderChildren(RendererBase.java:276) [richfaces-components-ui-4.1.0.Final.jar:]
    at org.richfaces.renderkit.html.AjaxOutputPanelRenderer.encodeChildren(AjaxOutputPanelRenderer.java:57) [richfaces-components-ui-4.1.0.Final.jar:]
.
. lots of RichFaces and JSF stuff
.
    at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:626) [jbossweb-7.0.7.Final.jar:]
    at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:2033) [jbossweb-7.0.7.Final.jar:]
    at java.lang.Thread.run(Unknown Source) [:1.7.0_02]
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:149) [hibernate-core-4.0.0.Final.jar:4.0.0.Final]
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:195) [hibernate-core-4.0.0.Final.jar:4.0.0.Final]
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185) [hibernate-core-4.0.0.Final.jar:4.0.0.Final]
    at de.poyry.pqgenerator.model.Company_$$_javassist_22.getDndType(Company_$$_javassist_22.java) [classes:]
    at sun.reflect.GeneratedMethodAccessor457.invoke(Unknown Source) [:1.7.0_02]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) [:1.7.0_02]
    at java.lang.reflect.Method.invoke(Unknown Source) [:1.7.0_02]
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:302) [jboss-el-api_2.2_spec-1.0.0.Final.jar:1.0.0.Final]
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
    at org.apache.el.parser.AstValue.getValue(AstValue.java:169) [jbossweb-7.0.7.Final.jar:]
    at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189) [jbossweb-7.0.7.Final.jar:]
    at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50) [weld-core-1.1.4.Final.jar:2011-11-22 20:01]
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
    at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:67) [jbossweb-7.0.7.Final.jar:]
    at org.apache.el.parser.AstDeferredExpression.getValue(AstDeferredExpression.java:44) [jbossweb-7.0.7.Final.jar:]
    at org.apache.el.parser.AstCompositeExpression.getValue(AstCompositeExpression.java:50) [jbossweb-7.0.7.Final.jar:]
    at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189) [jbossweb-7.0.7.Final.jar:]
    at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50) [weld-core-1.1.4.Final.jar:2011-11-22 20:01]
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
    ... 72 more

Понятия не имею, почему я получаю здесь исключение LazyInitializationException, учитывая, что компания Company не намекает на LAZY для Hibernate 4, а предыдущий вызов #{doc.company.name} работает нормально.

Обновление:

Я недавно проверил это на GlassFish 3.1.2, и все в порядке. Таким образом, я начинаю верить, что это некая проблема / несоответствие политики управления транзакциями JBoss AS 7 или JBoss AS.

Я предполагаю, что во время какой-либо транзакции к названию компании был получен доступ, и после закрытия менеджера сущностей был получен доступ к dndType, который еще не был разблокирован (тогда как name был) ... выглядит для меня как проблема обработки транзакций EJB (где у меня действительно есть дефицит) ...

Я скоро добавлю больше информации.

Ответы [ 2 ]

0 голосов
/ 05 апреля 2016

Вы должны попробовать это: fetch = FetchType.EAGER Это решает мою проблему.

0 голосов
/ 03 июня 2012

Проблема заключалась в том, что компания не была выбрана в заявлении - это так просто.Мне просто иногда удавалось в подобных ситуациях, что транзакция все еще была активной, поэтому эта транзакция, похоже, не выполнялась, но на самом деле другие тоже., метод, который получил список документов из БД, уже запущен, а транзакция уже прошла.

...