休止サーバーとJSF2アプリケーションがデプロイメントサーバーに移動し、突然org.hibernate.AssertionFailure:null idをスローします。すぐにスタックトレースとコードを提供しますが、最初に4つの重要な問題があります。
これは展開サーバー(Windows Sever 2008で実行されるJBossおよびMySql)でのみ発生します。開発マシン(Windoes 7 Proで実行されるTomcatおよびMySql)では発生せず、ステージング環境(Linuxで実行されるJbossおよびMySqlでも発生しません) )
これを調査すると、オブジェクトを挿入しようとするとこのエラーが発生するようです。しかし、単純なクエリを実行するとエラーが発生します。 (実際には、エラーが複数のページにランダムに表示されるため、さまざまなクエリが実行されます。)
エラーはたまにしかヒットしません。 Jbossの再起動を行うと消えますが、しばらくすると戻ります。また、一貫性がなく、一部のクリックでは存在し、他のクリックでは存在しません。ヒットした場合でも、ページを簡単に更新すると、正常に戻ります。
私はc3p0を使用しています(下の設定)
何が起こっているのでしょうか?
コードの詳細:
これはアドレスオブジェクトで発生します。完全な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:エントリ内のnull id(例外が発生した後にセッションをフラッシュしないでください)
セッション例外がの前に発生したことを示しますこのorg.hibernate.AssertionFailure
がスローされるポイント。
正確には、session.flush()
が発生したときにエラーが発生したポイントではなく、org.hibernate.AssertionFailure
がスローされます。
上記は事実であるため、結論として考えられるのは、何かが抑制元の例外である可能性があることです。
その他エラーの可能性のあるポイントを探してください:save()
またはsaveOrUpdate()
はおそらくnull
フィールドを持つエンティティを永続化しようとしていますテーブルの列NOT NULL
は何ですか?
ヒント:デバッグを支援するために、Session
オブジェクトとのすべての対話の後にsession.flush()
を追加してみてください(例session.save(obj)
、session.merge(obj)
など)。 org.hibernate.AssertionFailure
をより早く、実際の問題が発生している場所により近い場所で発生させることを願っています。 (もちろん、デバッグ後、これらのsession.flush()
を削除します。)
私の場合、real例外がtry/catch {}
ブロック内で発生し、そこでcatch
が例外を抑制しました(再スローも警告もしませんでした)。
私は並行性の問題に賭けますが、異なるレベルで発生する可能性があります。
これらの潜在的な問題の原因とは別に、スタックがトランザクションマネージャーと統合された接続プーリングでDataSource
を既に提供しているので、c3p0(おそらく噂...)を削除します。
@asdcjuniorは正解です。例外がスローされる前に何かが発生しました。
そのような状況では(1つのテストで単一のトランザクションを処理するときに統合テストで頻繁に発生します-@Transactionアノテーションなど)、メソッドを呼び出しています。
session.clear()
すべての「ダーティ」オブジェクトが現在のセッションから削除され、次のフラッシュが実行されたときに問題が発生しないため、役立ちます。
フローの例:
正しいフローの例:
それが役に立てば幸い ;)
おそらく、いくつかのHibernateのバグが発生しています。 (少なくともHibernate 3.3.2.GAにアップグレードすることをお勧めします。)
一方、Hibernateは、IDがNULL可能であれば、データベースにまだ保存されていない新しいオブジェクトと既にデータベースにあるオブジェクトとの違いを常に認識できるようになると、パフォーマンスが向上します。 addressID
のタイプをlong
からLong
に変更すると、おそらくこの問題を回避できます。
提供されたスタックトレースは、クエリがバッファされた書き込みをクエリが実行される前にデータベースにフラッシュすることを強制し、書き込みが失敗するため、クエリで問題が発生していることを示しています。おそらく他の人が見ている同じ挿入問題があります。
この問題に直面していたのは、try catchブロックを追加するだけで、catchブロックにseesion.clear()を記述しただけです。これで、残りのレコードを続行してデータベースに挿入できます
敬具:シャヒドフセインアッバシ
問題の流れ:
このエラーを軽減する多くの可能な方法があります:
Session.getCurrentSession.refresh(entity)を作成すると同じエラーが発生しますが、コードの問題ではなく、バグのように見えます。ユニットテストでこのエラーが発生します。テストの開始時にエンティティを更新しようとすると、そのエンティティがテスト設定で作成されます(junitの@Beforeアノテーションが付けられます)。奇妙なのは、同じクラスから3つのエンティティをランダムデータで同時にセットアップで作成し、作成された最初の2つを更新できるが、最後の1つで更新が失敗することです。たとえば、テストセットアップで3つのエンティティユーザーを作成した場合、user1とuser2を更新できますが、user3で失敗します。セットアップでエンティティを作成するコードの最後にsession.flush()を追加することで、これを解決できました。エラーは表示されず、表示されるはずですが、追加のフラッシュが必要な理由を説明できません。また、テストではクエリを実行できますが、refresh(entity)メソッドが失敗するため、エンティティがフラッシュなしでも実際にテストDBにあることを確認できます。
これは、文字列の長さがDBで許可されている長さより大きい場合に発生することがあります。
DataIntegrityViolationException
は、この例外に変換されます。これは、休止状態による奇妙な動作です。
そのため、指定された長さのエンティティのStringフィールドにColumn
注釈があり、実際の値がその長さより大きい場合、上記の例外がスローされます。
ジェネレータークラスの変更:
<generator class="identity" />
に
<generator class="assigned" />
org.hibernate.AssertionFailure:エントリ内のnull id(例外が発生した後にセッションをフラッシュしないでください)
これは私たちに起こったことであり、後世のためにいくつかの詳細を追加すると思いました。条件に違反する重複フィールドを持つエンティティを作成しようとしていたことがわかりました。
Caused by: org.hibernate.exception.ConstraintViolationException: Duplicate entry '' for key
'Index_schools_name'
ただし、作成が失敗したにもかかわらず、休止状態がセッションをcommitしようとしていたため、この例外はマスクされていました。作成が失敗した場合、IDが設定されなかったため、アサートエラーが発生しました。スタックトレースでは、休止状態がコミットされていることがわかりました。
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit
(HibernateTransactionManager.Java:480)
セッションをコミットするのではなく、ロールバックする必要がありました。これは、ロールバック構成の問題であることが判明しました。古いXML設定を使用しており、例外パスが正しくありませんでした。
<prop key="create*">PROPAGATION_REQUIRED,-org.x.y.LocalException</prop>
LocalException
パスは正しくなく、休止状態はエラーをスローしませんでした(または、起動ログの噴出に埋もれていました)。これはおそらく、注釈を使用していて、正しい例外を指定しない場合にも当てはまります。
// NOTE: that the rollbackFor exception should match the throws (or be a subclass)
@Transactional(rollbackFor = LocalException.class)
public void create(Entity entity) throws AnotherException {
休止状態の配線を修正すると、「重複エントリ」例外が正しく表示され、セッションは適切にロールバックされて閉じられました。
これに対するもう1つの問題は、休止状態がAssertionFailure
をスローしたときに、MySQLでトランザクションロックを保持していたため、手動で強制終了する必要があったことです。参照: https://stackoverflow.com/a/39397836/17985
これは、実行中のクエリとは関係ありません。これはフラッシュをトリガーするだけです。この時点で、Hibernateはエンティティに識別子を割り当てようとしていますが、何らかの理由で失敗したようです。
ジェネレータークラスを変更してみてください:
<generator class="identity"/>
それが違いを生むかどうかを確認してください。また、展開したデータベースのテーブルに正しい自動インクリメント列が設定されていることを確認しましたか?
あなたの問題は this one に似ているようです。
Hibernate設定ファイルにも同じ例外があります。
<property name="operateType" type="Java.lang.Integer">
<column name="operate_type" not-null="true" />
</property>
オブジェクトにnull値を渡すと、例外が発生します
"org.hibernate.AssertionFailure: null id in com.idex.auctions.model.Address entry",
Hibernayeが「not-null」プロパティをチェックするので、「not-null」プロパティを削除するか、「not-null」を「false」に設定することで問題が解決するためだと思います。
OK、私はこのスレッドの他の答えに基づいて特に研究を続けました。しかし、最終的には、生産期限に間に合わなかったため、緊急時の敗走を選択する必要がありました。そこで、休止状態を把握する代わりに、次の2つのことを行いました。
フォームの1つにフォーカスするために使用していたjQueryライブラリを削除しました。このようなバグは、null値をポストするフォームが原因で発生する可能性があることをどこかで読んだためです。 jQueryライブラリーがPrimeFacesにうまく適合せず、何らかの形で誤動作する可能性があると思われます。ただの予感。
ユーザーとアドレスの間に持っていた休止状態の実装関係を削除しました。 (1対多ではなく、1つだけが必要です)、必要なときに自分でコードを作成しました。幸いなことに、それは1つのページだけに大きな影響を与えたので、たいした作業ではありませんでした。
結論:私たちはライブになり、アプリケーションはエラーなしで数日間実行されました。したがって、このソリューションはきれいではないかもしれません-そして私は自分自身を誇りに思っていません-しかし、私は実行中のアプリと幸せなクライアントを持っています。
同じエラーが発生しました。私の場合は、この例外の前にcreate query with exceptionを実行したためです。例外がキャッチされ、catchブロックでトランザクションをロールバックしません。次に、この壊れたトランザクションを他の操作で使用し、数時間後に同じ例外が発生しました。最初に、フラッシュモードを手動に設定します
public final Session getCurrentSession()
{
Session session = sessionFactory.getCurrentSession();
session.setFlushMode(FlushMode.MANUAL);
return session;
}
その後、別の例外があり、実際に何が起こったのかを説明してくれました。次に、作成メソッドのcatchブロックでトランザクションのロールバックを行いました。そしてそれは私を助けました。
org.hibernate.AssertionFailure:エントリ内のnull ID(例外が発生した後にセッションをフラッシュしないでください)
ユーザーアクティビティのバージョン履歴を維持し、次の値を設定しようとすると、saveメソッドの使用中にこのエラーが発生しますsetCreatedBy(1); setModifiedBy(1); setCreationDate(); setChangeDate();
}これを解決するために上記のエラーが発生します。テーブルの列。
Created_By Modified_By Creation_Date Change_Date
この問題を解決するためにUpdateメソッドで同じエラーが発生する場合は、Update()メソッドをmerge()メソッドに変更する必要があります。