60

Hibernate および JSF2 アプリケーションがデプロイ サーバーに送られ、突然 org.hibernate.AssertionFailure: null id 例外がスローされます。すぐにスタック トレースとコードを提供しますが、最初に 4 つの重要な問題があります。

  1. これは、展開サーバー (Windows Sever 2008 で実行されている Jboss と MySql で実行されている) でのみ発生します。私の開発マシン (Windoes 7 Pro で実行されている Tomcat と MySql) では発生せず、ステージング環境 (Linux で実行されている Jboss と MySql で実行されています) でも発生しません。 .)

  2. これを調査すると、オブジェクトを挿入しようとすると、このエラーが発生するようです。しかし、単純なクエリを実行するとエラーが発生します。(実際には、エラーがいくつかのページでランダムにポップアップするため、さまざまなクエリが発生します。)

  3. エラーは時々しかヒットしません。Jboss を再起動すると消えますが、しばらくすると元に戻ります。また、一貫性がなく、あるクリックではそこにあり、他のクリックではそうではありません. ヒットしても、ページの単純な更新を行うと、正常に返されます。

  4. 私は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)
4

20 に答える 20

54

例外:

org.hibernate.AssertionFailure: null id in entry (例外が発生した後にセッションをフラッシュしないでください)

これがスローされるポイントの前にセッション例外が発生したことを示します。org.hibernate.AssertionFailure

正確には、 エラーが発生した時点ではなく、 が発生しorg.hibernate.AssertionFailureたときに がスローされます。session.flush()

上記は事実であるため、考えられる結論は次のとおりです。何かが元の例外を抑制している可能性があります。

したがって、エラーの可能性のある他のポイントを探してくださいsave():または、テーブルの列が?saveOrUpdate()nullNOT NULL


ヒント: デバッグを容易にするために、オブジェクトsession.flush()とのすべての対話の後にを追加してみてください (例: 、など)。これにより、実際の問題が発生している場所の近くで がより早く発生することが期待されます。(もちろん、デバッグ後は削除してください。)Sessionsession.save(obj)session.merge(obj)org.hibernate.AssertionFailuresession.flush()


私の場合、実際の例外は、例外が抑制されたtry/catch {}ブロック内でcatch発生していました (再スローも警告もしませんでした)。

于 2013-05-15T13:15:29.720 に答える
16

並行性の問題に賭けますが、さまざまなレベルで発生する可能性があります。

DataSourceこれらの潜在的な問題の原因は別として、スタックがトランザクションマネージャーと統合された接続プールをすでに提供しているため、c3p0(おそらく単なる噂...)を削除します。

于 2012-06-07T20:13:56.437 に答える
8

@asdcjunior が正しく答えました。例外がスローされる前に何かが発生しました。

そのような状況では (@Transaction アノテーションなど、1 つのテストで単一のトランザクションを処理する場合、統合テストでよく発生します)、次のメソッドを呼び出しています。

session.clear()

すべての「ダーティ」オブジェクトが現在のセッションから削除されるため、次のフラッシュが実行されたときに問題が発生しなくなります。

フロー例:

  • 割り当てエンティティを挿入します(単一の割り当てのみが存在する可能性のある制約付きの多対多の関係)->すべてOK
  • 同じ割り当てエンティティをもう一度挿入します->すべて問題ありません。この場合、コントローラーは何らかの悪い要求例外を返します。内部では、SpringがIntegrityViolationExceptionをスローします->テストではすべて問題ないようです
  • リポジトリを取得し、findAll().size() を実行して既存の割り当て済みの数をチェックし、割り当てが 1 つしかないことを確認します -> 上記の例外がスローされます;/何が起こったのですか? セッションにはまだダーティ オブジェクトが存在します。通常、セッションは破棄されます (コントローラーがエラーを返します) が、ここではデータベースに関してチェックする次のアサーションがあるため、ここでの解決策は、次のデータベース関連のメソッド実行の前に追加の session.clear() です。

正しいフローの例:

  • 割り当てエンティティを挿入する
  • 同じ割り当てエンティティを挿入する
  • session.clear()
  • リポジトリを取得し、findAll().size() を実行します

それが役に立てば幸い ;)

于 2015-05-28T08:07:40.647 に答える
4

おそらく、Hibernate のバグが発生している可能性があります。(少なくとも Hibernate 3.3.2.GA にアップグレードすることをお勧めします。)

一方、Hibernate は、ID が null 可能であるとより適切に動作するため、Hibernate は、データベースにまだ永続化されていない新しいオブジェクトと、データベースに既に存在するオブジェクトとの違いを常に認識できます。タイプをaddressIDfrom からlongto に変更すると、Longおそらく問題を回避できます。

あなたが提供したスタックトレースは、クエリが実行される前にクエリがバッファリングされた書き込みをデータベースにフラッシュすることを強制しているため、クエリで問題が発生していることを示しており、おそらく他の人が見ているのと同じ挿入の問題で書き込みが失敗しています。

于 2012-06-08T20:55:50.533 に答える
2

OK、私はこのスレッドの他の答えに基づいて研究を続けました。でも結局、制作の締め切りに間に合わなかったので、緊急ルートを選ばなければなりませんでした。したがって、休止状態を理解する代わりに、次の2つのことを行いました。

  1. フォームの1つに焦点を合わせるために使用していたjQueryライブラリを削除しました。これを行ったのは、フォームがnull値を投稿したためにこのタイプのバグが発生する可能性があることをどこかで読んだためです。jQueryライブラリがPrimeFacesとうまく連携せず、何らかのフォームが誤動作する原因になるのではないかと思いました。ただの予感。

  2. ユーザーとアドレスの間にある休止状態の実装された関係を強制終了しました。(1つだけが必要で、1つから多数ではありません)、必要に応じて自分でコードを記述しました。幸い、1ページにしか影響がなかったので、それほど手間はかかりませんでした。

結論:稼働を開始し、アプリケーションはエラーなしで数日間実行されました。したがって、このソリューションはきれいではないかもしれません-そして私は自分自身を誇りに思っていません-しかし私は実行中のアプリと幸せなクライアントを持っています。

于 2012-06-11T16:34:35.953 に答える
1

org.hibernate.AssertionFailure: null id in entry (例外が発生した後にセッションをフラッシュしないでください)

これはちょうど私たちに起こったので、後世のためにいくつかの詳細を追加すると思いました. 条件に違反する重複フィールドを持つエンティティを作成しようとしていたことが判明しました。

Caused by: org.hibernate.exception.ConstraintViolationException: Duplicate entry '' for key
'Index_schools_name'

ただし、作成が失敗したにもかかわらず、休止状態がセッションをコミットしようとしたため、この例外はマスクされていました。作成に失敗した場合、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/179850

于 2016-09-08T18:35:13.473 に答える
0

ハイバネート構成ファイルにも同じ例外があります。

<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」プロパティを削除するか、「false」に「not-null」を設定すると、問題が解決すると思います。

于 2016-11-23T03:36:02.857 に答える
0

ジェネレーター クラスの変更:

<generator class="identity" />

<generator class="assigned" />
于 2015-05-07T09:38:06.503 に答える
0

これは、実行中のクエリとは関係ありません。これはフラッシュをトリガーするだけです。この時点で、Hibernate はエンティティに識別子を割り当てようとしましたが、何らかの理由で失敗したようです。

ジェネレータークラスを変更してみてください:

<generator class="identity"/>

それが違いを生むかどうかを確認してください。また、展開したデータベースのテーブルに正しい自動インクリメント列が設定されていることを確認しましたか?

あなたの問題はこれに似ているようです

于 2012-06-10T22:16:51.707 に答える
-1

catch ブロックでトランザクションをロールバックします

于 2013-07-12T12:13:28.677 に答える