hibernate - “org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话”[重复]
Posted
技术标签:
【中文标题】hibernate - “org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话”[重复]【英文标题】:hibernate - "org.hibernate.LazyInitializationException: could not initialize proxy - no Session" [duplicate] 【发布时间】:2014-01-14 08:25:10 【问题描述】:抱歉,如果我的帖子重复,但我无法从另一个主题解决我的问题,所以我创建了这个主题。希望有人帮助我。我正在使用 Hibernate、JSF 和 Glassfish。
表关系
这是我的完整代码
customerBean(请求范围)
public class customerBean implements Serializable
private CustomerProfile selectedCustomer = new CustomerProfile();
private List<CustomerProfile> customer;
/** Creates a new instance of customerBean */
public customerBean()
public List<CustomerProfile> getCustomer()
customerDao cust_dao = new customerDao();
customer = cust_dao.findAll();
return customer;
public CustomerProfile getSelectedCustomer()
return selectedCustomer;
public void setSelectedCustomer(CustomerProfile selectedCustomer)
this.selectedCustomer = selectedCustomer;
public void btnUpdate()
customerDao cust_create = new customerDao();
String msg;
if(cust_create.updateCustomer(selectedCustomer))
msg = "Updated Successfully!";
else
msg = "Error. Please check again!";
FacesMessage massage = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, null);
FacesContext.getCurrentInstance().addMessage(null, massage);
customerDao
public class customerDao
public List<CustomerProfile> findAll()
List<CustomerProfile> list_cust = null;
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
String sql = "FROM CustomerProfile";
try
session.beginTransaction();
list_cust = session.createQuery(sql).list();
session.beginTransaction().commit();
catch(Exception e)
session.beginTransaction().rollback();
return list_cust;
public boolean updateCustomer(CustomerProfile customer)
boolean flag;
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
try
session.beginTransaction();
CustomerProfile cust_info = (CustomerProfile) session.load(CustomerProfile.class, customer.getProfile());
cust_info.setFullname(customer.getFullname());
cust_info.setEmail(customer.getEmail());
cust_info.setPhone(customer.getPhone());
session.merge(customer);
session.beginTransaction().commit();
flag = true;
catch(Exception e)
flag = false;
e.printStackTrace();
session.beginTransaction().rollback();
return flag;
xhtml
<p:growl id="msgs" showDetail="true" />
<h:form id="formData">
<p:dataTable id="customers" var="customer_profile" value="#customerBean.customer" paginator="true" paginatorPosition="bottom" rows="10"
paginatorTemplate="PreviousPageLink PageLinks NextPageLink RowsPerPageDropdown"
rowsPerPageTemplate="5,10,15">
<p:column headerText="Customer ID">
<h:outputText value="#customer_profile.customer.customId" />
</p:column>
<p:column headerText="Full Name">
<h:outputText value="#customer_profile.fullname" />
</p:column>
<p:column headerText="Phone">
<h:outputText value="#customer_profile.phone" />
</p:column>
<p:column headerText="Email">
<h:outputText value="#customer_profile.email" />
</p:column>
<p:column headerText="Order">
<h:outputText value="#customer_profile.quantityOrder" />
</p:column>
<p:column headerText="Date Created">
<h:outputText value="#customer_profile.dateCreated" />
</p:column>
<p:column>
<p:commandButton id="btnUpdate" oncomplete="updateDialog.show()" icon="ui-icon-search" title="Update" update=":formUpdate">
<f:setPropertyActionListener value="#customer_profile" target="#customerBean.selectedCustomer" />
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
<!-- Start formUpdate -->
<h:form id="formUpdate">
<p:dialog header="Customer Details" widgetVar="updateDialog" resizable="false" id="updateDlg" showEffect="fade" hideEffect="explode">
<h:panelGrid id="display" columns="2" cellpadding="4" style="margin:0 auto;">
<h:outputText value="Profile ID: " />
<h:outputLabel value="#customerBean.selectedCustomer.profile" />
<h:outputLabel value="#customerBean.selectedCustomer.customer.loginName" />
<h:outputText value="Full Name: " />
<h:inputText value="#customerBean.selectedCustomer.fullname" />
<h:outputText value="Phone: " />
<h:inputText value="#customerBean.selectedCustomer.phone" />
<h:outputText value="Email: " />
<h:inputText value="#customerBean.selectedCustomer.email" />
<f:facet name="footer">
<p:separator />
<p:commandButton id="btnOK" immediate="true" oncomplete="updateDialog.hide()" action="#customerBean.btnUpdate" icon="ui-icon-search" title="Save" value="Save" update=":formData, :msgs" />
<p:commandButton id="btnCancel" oncomplete="updateDialog.hide()" icon="ui-icon-search" title="Cancel" value="Cancel" />
</f:facet>
</h:panelGrid>
</p:dialog>
</h:form>
<!-- End formUpdate -->
我收到了这个错误:
严重:javax.el.ELException:/admin/customer_list.xhtml @68,106 value="#customerBean.selectedCustomer.customer.loginName": org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话
更新
Customer.hbm.xml
<hibernate-mapping>
<class catalog="catering" name="entities.Customer" schema="dbo" table="customer">
<id name="customId" type="int">
<column name="customID"/>
<generator class="assigned"/>
</id>
<property name="loginName" type="string">
<column name="loginName" not-null="true" unique="true"/>
</property>
<property name="password" type="string">
<column name="password"/>
</property>
<set inverse="true" name="customerProfiles">
<key>
<column name="customID"/>
</key>
<one-to-many class="entities.CustomerProfile"/>
</set>
<set inverse="true" name="orderses">
<key>
<column name="customID" not-null="true"/>
</key>
<one-to-many class="entities.Orders"/>
</set>
</class>
</hibernate-mapping>
Customer.java
public class Customer implements java.io.Serializable
private int customId;
private Serializable loginName;
private Serializable password;
private Set customerProfiles = new HashSet(0);
private Set orderses = new HashSet(0);
public Customer()
public Customer(int customId, Serializable loginName)
this.customId = customId;
this.loginName = loginName;
public Customer(int customId, Serializable loginName, Serializable password, Set customerProfiles, Set orderses)
this.customId = customId;
this.loginName = loginName;
this.password = password;
this.customerProfiles = customerProfiles;
this.orderses = orderses;
public int getCustomId()
return this.customId;
public void setCustomId(int customId)
this.customId = customId;
public Serializable getLoginName()
return this.loginName;
public void setLoginName(Serializable loginName)
this.loginName = loginName;
public Serializable getPassword()
return this.password;
public void setPassword(Serializable password)
this.password = password;
public Set getCustomerProfiles()
return this.customerProfiles;
public void setCustomerProfiles(Set customerProfiles)
this.customerProfiles = customerProfiles;
public Set getOrderses()
return this.orderses;
public void setOrderses(Set orderses)
this.orderses = orderses;
CustomerProfile.hbm.xml
<hibernate-mapping>
<class catalog="catering" name="entities.CustomerProfile" schema="dbo" table="customer_profile">
<id name="profile" type="int">
<column name="profile"/>
<generator class="assigned"/>
</id>
<many-to-one class="entities.Customer" fetch="select" name="customer">
<column name="customID"/>
</many-to-one>
<property name="gender" type="java.lang.Boolean">
<column name="gender"/>
</property>
<property name="fullname" type="string">
<column name="fullname" not-null="true"/>
</property>
<property name="phone" type="string">
<column length="15" name="phone" not-null="true"/>
</property>
<property name="email" type="string">
<column name="email"/>
</property>
<property name="quantityOrder" type="java.lang.Integer">
<column name="quantityOrder"/>
</property>
<property name="isVegetarian" type="java.lang.Boolean">
<column name="isVegetarian"/>
</property>
<property name="dateCreated" type="date">
<column name="dateCreated"/>
</property>
</class>
</hibernate-mapping>
CustomerProfile.java
public class CustomerProfile implements java.io.Serializable
private int profile;
private Customer customer;
private Boolean gender;
private Serializable fullname;
private String phone;
private Serializable email;
private Integer quantityOrder;
private Boolean isVegetarian;
private Serializable dateCreated;
public CustomerProfile()
public CustomerProfile(int profile, Serializable fullname, String phone)
this.profile = profile;
this.fullname = fullname;
this.phone = phone;
public CustomerProfile(int profile, Customer customer, Boolean gender, Serializable fullname, String phone, Serializable email, Integer quantityOrder, Boolean isVegetarian, Serializable dateCreated)
this.profile = profile;
this.customer = customer;
this.gender = gender;
this.fullname = fullname;
this.phone = phone;
this.email = email;
this.quantityOrder = quantityOrder;
this.isVegetarian = isVegetarian;
this.dateCreated = dateCreated;
public int getProfile()
return this.profile;
public void setProfile(int profile)
this.profile = profile;
public Customer getCustomer()
return this.customer;
public void setCustomer(Customer customer)
this.customer = customer;
public Boolean getGender()
return this.gender;
public void setGender(Boolean gender)
this.gender = gender;
public Serializable getFullname()
return this.fullname;
public void setFullname(Serializable fullname)
this.fullname = fullname;
public String getPhone()
return this.phone;
public void setPhone(String phone)
this.phone = phone;
public Serializable getEmail()
return this.email;
public void setEmail(Serializable email)
this.email = email;
public Integer getQuantityOrder()
return this.quantityOrder;
public void setQuantityOrder(Integer quantityOrder)
this.quantityOrder = quantityOrder;
public Boolean getIsVegetarian()
return this.isVegetarian;
public void setIsVegetarian(Boolean isVegetarian)
this.isVegetarian = isVegetarian;
public Serializable getDateCreated()
return this.dateCreated;
public void setDateCreated(Serializable dateCreated)
this.dateCreated = dateCreated;
【问题讨论】:
【参考方案1】:这可能无关,但我发现这种模式有问题。
try
session.beginTransaction();
// do something
session.beginTransaction().commit();
catch(Exception e)
session.beginTransaction().rollback();
您不应调用 3 次 beginTransaction。 我的意思是,我怀疑您的代码是否符合您的要求。
查看本页顶部,了解此模式的外观。
http://docs.jboss.org/hibernate/annotations/3.5/api/org/hibernate/Session.html
【讨论】:
@peter-petrov 当我更新客户信息时,我收到此错误“严重:org.hibernate.ObjectNotFoundException:不存在具有给定标识符的行:[entities.CustomerProfile#0]”【参考方案2】:当您与其他实体有关系时,Hibernate 使用代理对象,此代理仅在需要时帮助从数据库获取信息,因此它的机制称为延迟初始化,并获取它需要会话对象的信息,您列表中的对象客户未初始化,因此您需要这样做,明确说明:
public List<CustomerProfile> findAll()
List<CustomerProfile> list_cust = null;
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
String sql = "FROM CustomerProfile";
try
session.beginTransaction();
list_cust = session.createQuery(sql).list();
for (CustomerProfile cp : list_cust)
Hibernate.initialize(cp.getCustomer());
//or cp.getCustomer().getLoginName();
session.beginTransaction().commit();
catch(Exception e)
session.beginTransaction().rollback();
return list_cust;
【讨论】:
它说“客户在entities.CustomerProfile中有私人访问权限” 你可以试试用 cp.getCustomer().getLoginName() 代替 Hibernate.initialize 谢谢你现在我可以从客户表中获取信息。但我还有 2 个额外的问题。 1) 为什么只需要 cp.getCustomer().getLoginName()。 2)当我更新客户信息时,我收到此错误“严重:org.hibernate.ObjectNotFoundException:不存在具有给定标识符的行:[entities.CustomerProfile#0]” 好的,第一个问题,(我更新我的答案以使用 Hibernate.initialize)当您调用代理对象(客户)的 getter 时,只有在那一刻,hibernate 才会在数据库中进行选择以获取该字段的信息。所以这可以回答第二个问题,客户ID字段从未初始化我不确定代理对象如何在休眠状态下工作,但在其他ORM中作为eclipse链接或openjpa,当您访问代理的字段时,所有对象都已填充,也许这不是休眠的情况,所以尝试以我更新答案的方式使用 Hibernate.initialize。 感谢迭代部分!!!以上是关于hibernate - “org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话”[重复]的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate卡住,然后报错java.sql.SQLException: Unknown system variable 'language'异常
如果 mysql 不存在 Hibernate 4 和 spring 4,则不会自动创建模式