org.hibernate.AssertionFailure:入口中的空id(异常发生后不刷新Session)
我有一个 hibernate 和 JSF2 应用程序去部署服务器,突然抛出一个 org.hibernate.AssertionFailure: null id in exception.我将立即提供堆栈跟踪和代码,但首先有四个重要问题:
I have a hibernate and JSF2 application going to the deployment server and suddenly throwing an org.hibernate.AssertionFailure: null id in exception. I will provide the stack trace and code immediately but here are four important issues first:
这只发生在部署服务器上(Jboss & MySql 在 Windows Sever 2008 上运行.)它不会发生在我的开发机器上(Tomcat 和 MySql 在 Windoes 7 Pro 上运行),也不会在登台环境中发生(Jboss 和 MySql 在 Linux 上运行.)
This happens only on the deployment server (Jboss & MySql running on Windows Sever 2008.) It does not happen on my development machine (Tomcat and MySql running on Windoes 7 Pro) and also not on the staging environment (Jboss and MySql running on Linux.)
研究这个,似乎人们在尝试插入一个对象时会得到这个错误.但是当我做一个简单的查询时我得到了错误.(实际上是各种不同的查询,因为错误会随机出现在几个页面上.)
Researching this, it seems that people get this error when trying to insert an object. But I get the error when I'm doing a simple query. (various different queries, actually, as the error pops up on several pages randomly.)
错误只是偶尔出现.如果我重新启动 Jboss,它就会消失,但过一段时间又会回来.此外,它并不一致,在某些点击时它存在,而在其他点击时则不存在.即使它命中,当我对页面进行简单的刷新时,它也能正常返回.
The error hits only every now and then. If I do a Jboss restart it goes away, but a time later returns. Also, it's not consistent, on some clicks it's there, on others it's not. Even when it hits, when I do a simple refresh of the page it returns fine.
我正在使用 c3p0(配置如下)
I'm using c3p0 (config below)
知道发生了什么吗?
代码详情:
这发生在地址对象上.这是完整的 hbm:
This happens on an address object. Here's the full hbm:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.idex.auctions.model">
<class name="Address" table="address" lazy="true">
<id name="addressID" column="AddressID">
<generator class="native"/>
</id>
<property name="street" column="street"/>
<property name="city" column="city"/>
<property name="zip" column="zip"/>
<property name="state" column="state"/>
<property name="region" column="region"/>
<property name="country" column="country"/>
<many-to-one name="user"
class="com.idex.auctions.model.User"
column="userid"
unique="true"
cascade="save-update"/>
</class>
</hibernate-mapping>
Java 类很简单:
public class Address implements Serializable {
private static final long serialVersionUID = 7485582614444496906L;
private long addressID;
private String street;
private String city;
private String zip;
private String state;
private String region;
private String country;
private User user;
public Address() {
}
public long getAddressID() {
return addressID;
}
public void setAddressID(long addressID) {
this.addressID = addressID;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
c3p0 配置:
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_period">1000</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">0</property>
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
使用的版本是
hibernate3.jar
c3p0-0.9.1.2.jar
myfaces-api-2.1.4.jar
myfaces-impl-2.1.4.jar
mysql-connector-java-5.1.20-bin.jar
完整的堆栈跟踪
org.hibernate.AssertionFailure: null id in com.idex.auctions.model.Address entry
(don't flush the Session after an exception occurs)
org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(
DefaultFlushEntityEventListener.java:78)
org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(
DefaultFlushEntityEventListener.java:187)
org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(
DefaultFlushEntityEventListener.java:143)
org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(
AbstractFlushingEventListener.java:219)
org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(
AbstractFlushingEventListener.java:99)
org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(
DefaultAutoFlushEventListener.java:58)
org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:997)
org.hibernate.impl.SessionImpl.list(SessionImpl.java:1142)
org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
com.idex.auctions.manager.DatabaseManager.getAllObjects(DatabaseManager.java:464)
com.idex.auctions.ui.NavBean.gotoHome(NavBean.java:40)
sun.reflect.GeneratedMethodAccessor350.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
javax.el.BeanELResolver.invokeMethod(BeanELResolver.java:735)
javax.el.BeanELResolver.invoke(BeanELResolver.java:467)
javax.el.CompositeELResolver.invoke(CompositeELResolver.java:246)
org.apache.el.parser.AstValue.getValue(AstValue.java:159)
org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression.getValue(
ContextAwareTagValueExpression.java:96)
javax.faces.component._DeltaStateHelper.eval(_DeltaStateHelper.java:246)
javax.faces.component.UIOutcomeTarget.getOutcome(UIOutcomeTarget.java:50)
org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils.getOutcomeTargetHref(
HtmlRendererUtils.java:1542)
org.apache.myfaces.shared.renderkit.html.HtmlLinkRendererBase.renderOutcomeLinkStart(
HtmlLinkRendererBase.java:908)
org.apache.myfaces.shared.renderkit.html.HtmlLinkRendererBase.encodeBegin(
HtmlLinkRendererBase.java:143)
javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:502)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:744)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:758)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:758)
org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(
FaceletViewDeclarationLanguage.java:1900)
org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:285)
com.ocpsoft.pretty.faces.application.PrettyViewHandler.renderView(
PrettyViewHandler.java:163)
javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:59)
org.apache.myfaces.tomahawk.application.ResourceViewHandlerWrapper.renderView(
ResourceViewHandlerWrapper.java:93)
com.idex.auctions.ui.CustomViewHandler.renderView(CustomViewHandler.java:98)
org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:115)
org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:241)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:199)
com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:126)
com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:118)
推荐答案
例外:
org.hibernate.AssertionFailure: 入口为空id(异常发生后不刷新Session)
org.hibernate.AssertionFailure: null id in entry (don't flush the Session after an exception occurs)
告诉我们会话异常发生在之前这个org.hibernate.AssertionFailure
被抛出.
Tells us that that the session exception has happened before the point where this org.hibernate.AssertionFailure
is thrown.
确切地说,org.hibernate.AssertionFailure
在 session.flush()
发生时抛出,而不是发生错误的点.
To be exact, the org.hibernate.AssertionFailure
is thrown when the session.flush()
is happening, not the point where the error ocurred.
以上是事实,因此可能得出的结论是:某些东西可能抑制原始异常.
The above is a fact, thus a possible conclusion from it is: something could be suppressing the original exception.
所以寻找其他可能的错误点:save()
或 saveOrUpdate()
可能试图持久化一个具有 null
字段 的实体,其中表中的列是 NOT NULL
吗?
So look for other possible points of error: A save()
or saveOrUpdate()
is possibly trying to persist an entity with a null
field where, in the table, the column is NOT NULL
?
提示:为了帮助调试,尝试在每次与 Session
对象(例如 session.save(obj)
交互后添加一个 session.flush()
、session.merge(obj)
等),这有望导致 org.hibernate.AssertionFailure
更早发生,更接近真正的问题发生的地方.(当然,调试后,去掉那些session.flush()
.)
TIP:
To help in the debugging, try adding a session.flush()
after every interaction with the Session
object (e.g. session.save(obj)
, session.merge(obj)
, etc.), this will hopefully cause the org.hibernate.AssertionFailure
to happen earlier, closer to where the real problem is taking place. (Of course, after the debugging, remove those session.flush()
.)
就我而言,真正的异常发生在 try/catch {}
块内,其中 catch
抑制了异常(没有重新抛出或警告我).
In my case, the real exception was taking place inside a try/catch {}
block where the catch
suppressed the exception (didn't rethrow or warn me about it).
相关文章