sql >> データベース >  >> RDS >> Oracle

Oracleを使用してHibernateに最後に挿入された行のIDを取得できません

    例外'このクラスのIDは、save()を呼び出す前に手動で割り当てる必要があります'は、'Assigned'の識別子生成戦略を使用していることを意味します。

    割り当て済み save()が呼び出される前に、アプリケーションがオブジェクトに識別子を割り当てられるようにします。これは、要素が指定されていない場合のデフォルトの戦略です。

    ストラテジーを定義しない場合、休止状態のデフォルトは「割り当て済み」です。 「割り当てられた」戦略は、休止状態がアプリケーションが独自のIDを提供することを期待していることを意味します。

    OracleでシーケンスIDジェネレータを使用する場合は、次の構成で使用できます-

    xmlを使用している場合-

       <id name="countryId" type="java.lang.Integer">  
            <column name="Country_Id" />  
            <generator class="sequence">  
                <param name="sequence">Country_Id_Seq</param>               
            </generator>  
        </id>
    

    注釈を使用している場合-

       @Id
       @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="Country_Id_Seq")
       @SequenceGenerator(name="Country_Id_Seq", sequenceName="Country_Id_Seq"  )
       private Integer sequence;
    

    そして、あなたのコードはそのように見えるはずです-

    Country c=new Country();
    
    c.setCountryName(request.getParameter("txtCountryName"));
    c.setCountryCode(request.getParameter("txtCountryCode"));
    Zone z=(Zone) session.get(Zone.class, new BigDecimal(request.getParameter("zoneId")));
    c.setZone(z);
    session.save(c);
    
    session.flush();    
    System.out.println(c.getCountryId()); 
    

    'session.save(c)'が実行されると、hibernateはOracleに対して次のSQL呼び出しを行い、IDを取得してCountryオブジェクトに設定します。

    select Country_Id_Seq.nextVal from dual;
    

    トリガーの問題

    行が挿入されたときにトリガーを使用してIDをインクリメントしているため、休止状態のシーケンスで問題が発生します。 Hibernateはシーケンスを使用してIDを生成し、データベースはトリガーを使用してIDをインクリメントしています。これにより、IDが2回インクリメントされます。

    これを解決するには、3つのオプションがあります。

    1. トリガーは不要なので削除してください。

    2. テーブルがアプリケーションの外部で更新される可能性があるためにトリガーが必要な場合は、シーケンスからIDを生成するためのOracleTriggerのinsertstatementHIbernateの問題でIDが設定されていない場合にのみIDが生成されるようにトリガーを更新できます。

    3. データがdbに保存される前に、トリガーを使用してデータにIDを設定するカスタムIDジェネレーターを作成します。次のリンクを確認してください-https://forum.hibernate.org/viewtopic.php?t=973262



    1. SQL Server(SSMS)でデータベースメールを設定する方法

    2. 空の配列を持つレコードを取得するときに問題が発生します

    3. 大きなテーブルでOFFSETを使用してクエリを最適化する

    4. 一度に複数のデータベースを照会する