1
@Entity
@Table(name = "J_CNTRY")
public class CountryEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "myTableGenerator")
    @TableGenerator(name = "myTableGenerator", allocationSize = 5, pkColumnName = "pkName", valueColumnName = "pkValue", table = "j_cntry_pk_table")
    private Long id;

    private String country;

    @Generated(GenerationTime.INSERT)
    @Column(name = "CREATION_TIME", columnDefinition = "DATE default '15-JUL-1980'", insertable = false)
    private Date creationTime;

    public CountryEntity() {
    }

    public Long getId() {
        return id;
    }

    public void setId(final Long id) {
        this.id = id;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(final String country) {
        this.country = country;
    }

    public Date getCreationTime() {
        return creationTime;
    }

    @Override
    public String toString() {
        return "Country [id=" + id + ", country=" + country + ", creationTime="
                + creationTime + "]";
    }

}

値を設定しない場合、値「15-JUL-1980」が各行に挿入されることを期待しています。

しかし、期待どおりに機能していません。私はここで何か間違ったことをしていますか?

いくつかの理由で、データベースではなくアプリケーションでデフォルト値を設定したいと思います。

更新

最初は、「挿入可能=false」のみを使用せずに試しました。

初心者として、私はさまざまなオプションを試していて、そのオプションを維持していました。

これが私が実行しているテストケースです:

@Test
    public void testCreateCountry4() {
        final CountryEntity a1 = new CountryEntity();
        a1.setCountry("Xxxx");
        final Session currentSession = sessionFactory.getCurrentSession();
        final Long savedId = (Long) currentSession.save(a1);
        System.out.println("Saved with ID = " + savedId);
        currentSession.flush();
        System.out.println("Saved object = " + a1);
        assertNotNull(savedId);
    }

そしてそれが生成した出力:

Saved with ID = 85
Hibernate: 
    /* insert entities.CountryEntity
        */ insert 
        into
            J_CNTRY
            (country, id) 
        values
            (?, ?)
Hibernate: 
    /* get generated state entities.CountryEntity */ select
        countryent_.CREATION_TIME as CREATION3_2_ 
    from
        J_CNTRY countryent_ 
    where
        countryent_.id=?
Saved object = Country [id=85, country=Xxxx, creationTime=null]

テーブル:

CREATE TABLE "FOO"."J_CNTRY" 
   (    "ID" VARCHAR2(255 BYTE) NOT NULL, 
    "COUNTRY" VARCHAR2(255 BYTE), 
    "CREATION_TIME" DATE, 
     CONSTRAINT "J_CNTRY_PK" PRIMARY KEY ("ID")
}
4

1 に答える 1

2

値を設定しない場合、値「15-JUL-1980」が各行に挿入されることを期待しています。

実際にはcreationTime、値を設定したとしても、insertable = false.

しかし、期待どおりに機能していません。私はここで何か悪いことをしていますか?

正確に機能していないのは何ですか? テーブルの DDL スクリプトを表示できますか? どの DML INSERT ステートメントが正確に実行されますか? Oracle はデフォルトを適切に設定しますか? 挿入後にエンティティに戻さないのですか?いつ失敗しますか?

念のため、 のTemporal注釈が抜けていませんcreationTimeか? JPA 1.0仕様によると:

9.1.20 時間注釈

タイプおよびの永続フィールドまたはプロパティには、注釈を指定する 必要Temporalあります。これらのタイプのフィールドまたはプロパティに対してのみ指定できます。java.util.Datejava.util.Calendar

を追加し@Temporal(TemporalType.DATE)ます。

これで問題が解決するかどうかはわかりませんが、上記の質問に答えることが問題の診断に役立つ場合があります。


挿入しようとするときはいつでも、Hibernate にデフォルト値を設定してもらいたいです。私が示した表は、テスト/学習目的で作成したダミーの表です。元のテーブルはレガシー テーブルであり、'DEFAULT' 属性が設定されていません。混乱して申し訳ありません。

注釈のcolumnDefinition要素は、列の DDL を生成するときに使用される SQL フラグメントを指定するために使用されます。それだけです。JPA プロバイダーを使用して DDL を生成せず、テーブルに何も定義されていない場合、何も起こりません。ColumnDEFAULT

したがって、あなたの場合、おそらくライフサイクルコールバックを使用して、次の場合に日付を設定しnullますPrePersist:

@Entity
public class Account {
    ...

    @PrePersist
    protected void setCreationDateIfRequired() {
        if (getCreationDate() == null) {
            setCreationDate(...);
        }
    }

}

参照

  • JPA 1.0 仕様
    • 3.5.1項「ライフサイクル・コールバック・メソッド」
于 2010-09-12T18:42:12.090 に答える