Получавам LazyInitializationException
, когато моят JSF
изглед изисква списък с деца за обект. Не използвам Hibernate
директно, а JPA
. Таблицата CHILD DB има FK на таблицата PARENT. Това е много стандартна връзка.
Ето как изглеждат съответните извадки от кода:
Родител
@Entity
@Table(name="PARENT")
@NamedQueries({@NamedQuery(name = "Parent.getByID",
query = "SELECT i FROM Parent i WHERE i.parentID = :parentID")})
public class Parent implements Serializable {
@Id
@SequenceGenerator(name="PARENT_SEQ_GEN", sequenceName="DB_SEQ", allocationSize = 1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="PARENT_SEQ_GEN")
@Column(name="PARENT_ID")
private long parentID;
/* other stuff */
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", fetch = FetchType.LAZY)
private List<Child> childList;
/* other stuff */
public List<Child> getChildren() {
return this.childList;
}
Дете
@Entity
@Table(name="CHILD")
@NamedQueries({@NamedQuery(name = "Child.getByID",
query = "SELECT i FROM Child i WHERE i.childID = :childID")})
public class Child implements Serializable {
@Id
@SequenceGenerator(name="CHILD_SEQ_GEN", sequenceName="DB_SEQ", allocationSize = 1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="CHILD_SEQ_GEN")
@Column(name="CHILD_ID")
private long childID;
@JoinColumn(name = "PARENT_ID", referencedColumnName = "PARENT_ID", insertable = true, updatable = false)
@ManyToOne(optional = false)
private Parent parent;
Преглед
<h:dataTable id="childTbl" value="#{parent.children}"
var="child" width="100%"
styleClass="data" border="1" cellpadding="2"
cellspacing="0">
<h:column>
<f:facet name="header">Child Name</f:facet>
#{child.name}
</h:column>
<h:column>
<f:facet name="header">DOB</f:facet>
#{child.dob}
</h:column>
</h:dataTable>
Ако променя FetchType
на EAGER
, не получавам изключение, но искам извличането на данни да е мързеливо, т.е. само при поискване. Какво трябва да променя, за да избегна това изключение?
Може да е свързано
В изгледа, който се изобразява успешно, когато FetchType
е EAGER
, имам формуляр за добавяне на дете за всеки родител и след като бъде добавено дете, се опитвам да използвам f:ajax
, за да опресня автоматично списъка с деца:
<h:commandButton value="Add Child" action="#{parentBean.addChild}">
<f:ajax execute="@form" render="childTbl"/>
</h:commandButton>
Това опресняване обаче е неуспешно, тъй като дъщерната таблица не се актуализира с нов ред, когато добавя дъщерен елемент към AJAX (което правя, за да избегна презареждането на страницата), въпреки че съответната DB транзакция е успешна. Новодобавеното дете се вижда само в таблицата, когато опресня изгледа в браузъра, като презаредя страницата.
Обърнете внимание обаче, че LazyInitializationException
се появява, когато за първи път се опитам да заредя страницата с родител и техните деца, когато FetchType
е LAZY
. Това не е пряко свързано с неуспешното опресняване, което се случва, когато FetchType
е EAGER
. Но си помислих, че може да има някакъв основен пропуск в моя код, който, когато бъде коригиран, ще позволи както мързелива инициализация, така и опресняване на AJAX изгледа.
<f:ajax execute="@form" render="childTbl"/>
трябва да направи това - person amphibient   schedule 20.05.2015#{parent.children}
. Предполагам, че EL се отнася доprivate List<Child> childList
, върнат отgetChildren()
в обектаParent
. Това няма нищо общо с JSF. Използвайте отделна заявка, за да извлечете списък с деца въз основа на неговия родителски ред в зависимост от функционалните изисквания или структурата/потока на проекта. - person Tiny   schedule 20.05.2015