2016-03-23 11 views
3

JPAを使用して、ソースからデータを取得してデータベースに取得するサービスを行っています。 idはシーケンスを使用して生成されます。 私は、このコマンドを使用して、私のDBにシーケンスを作成しました:データベースに直接作成せずにJPAでシーケンスを作成する方法

CREATE SEQUENCE crm_test_sq_1 MINVALUE 1 MAXVALUE 999999999999999999999999999 START WITH 1 INCREMENT BY 1 CACHE 100 NOCYCLE 

しかし、私は私のコードから直接シーケンスを作成する方法がわかりません。誰でも私にこの問題を理解させてください。どうもありがとうございます!

私のモデルクラス、modeltest.java:

@Entity 
    @Table(name = "MODEL_TEST") 

    @JsonPropertyOrder({ "ID", "CODE", "NAME" }) 
    @XmlRootElement 
    @NamedQueries({ 
     @NamedQuery(name = "modeltest.getall", query = "SELECT e FROM modelteste"), 
     @NamedQuery(name = "modeltest.deleteAll", query = "DELETE FROM modeltest e")}) 
    public class modeltest implements Serializable { 
     private static final long serialVersionUID = 1L; 

     @Id 
     @GeneratedValue(generator = "crm_test_sq", strategy = GenerationType.SEQUENCE) 
     @SequenceGenerator(name = "crm_test_sq", sequenceName = "crm_test_sq",allocationSize=1) 
     @Column(name="ID", unique=true, nullable=false, precision=10, scale=0) 
     private Long id; 

     @Column(name = "CODE") 
     private String isocurrencycode; 

     @Column(name = "NAME") 
     private String currencyname; 

     public modeltest() { 
     } 
//........... getter and setter method 

マイDAOクラス、modeltestDao.java

public Boolean saveData() { 


//............................................ 
      getEntityManager().createNamedQuery("modeltest.deleteAll").executeUpdate(); 

      // i want something like below, but obviously this line of code give me an error 
      getEntityManager().createNativeQuery ("CREATE SEQUENCE crm_test_sq_1 MINVALUE 1 MAXVALUE 999999999999999999999999999 START WITH 1 INCREMENT BY 1 CACHE 100 NOCYCLE").executeUpdate(); 

     /.................... 
     return true; 
    } 

EDIT:ところで、私はシーケンスをリセットすると仮定する理由は、私は実行するたびにあります例えば、最初にデータを実行すると、idは1で始まり10で終了し、2回目にはデータを実行し、idは11で始まり、20で終わります(データをデータベースに取り込みます)。この問題は、サーバーを再起動すると停止するだけです。

For example: 
call saveData() first time 
DATA IN TABLE: 
ID 1 2 3 4 5 
call saveData() second time 
DATA IN TABLE: 
ID 6 7 8 9 10 

他のデータは変更されませんが、idです。だから、私はsaveData()を実行するたびにこれを解決し、シーケンスを再作成する方法を見つける

+0

サイドノート:あなたのユースケースが有効である、とあなたが本当にこれらすべてのレコードを削除し、シーケンスをリセットする必要がある、とは、Oracle 12cとを使用している場合、あなたはこのような何かを行うことができます

私がお勧めしますLiquibaseなどのツールを使用してdbスキーマを維持します。 Liquibaseは配列をサポートします。 Liquibaseなどのツールを使用すると、列のデータを失うことなく列の名前を変更します。 JPAは、通常、dbテーブルの最初の作成時にのみ役立ちます。 – Puce

+0

サイドノート2(JsonPropertyOrder):通常、JsonPropertyOrderアノテーションを使用してJPAエンティティを外部クライアントにエクスポートすることをお勧めしません。理由:悪意のあるクライアントがdbの主キーを改ざんする可能性があります。ビジネスキーだけを公開し、技術的なIDは公開しない方がよいでしょう。 – Puce

+0

ありがとう、私のポストに答えるために、私は何をしたいシーケンスを削除し、私はsaveData()関数を実行するたびにそれを再作成する(なぜ私はこれを行う理由は、データベースのキャッシュIDを避けるためです)。したがって、私は私のコードに私のシーケンスの作成とドロップコマンドをスティックする必要があります。私が意味することを望みますか? – minh

答えて

4

あなたの提案にコードの臭いがあります。最初にシーケンスのデータベースキャッシングを避ける必要があるのはなぜですか?シーケンスのポイントは一意の識別子を生成することです。そのため、アプリケーションの実行中にシーケンスを再作成しないでください。

このメソッドでシーケンスを作成する場合は、そのメソッドが複数のスレッドによって同時に呼び出されたときに何が起こるかを想像してください。

entityManager.createNativeQuery(
    "ALTER SEQUENCE crm_test_sq_1 RESTART START WITH 1") 
.executeUpdate(); 
+0

こんにちは、あなたのコードを試しました。それは私にエラーを与えます: "org.hibernate.util.JDBCExceptionReporter:ORA-02286:ALTER SEQUENCEのオプションが指定されていません"。 – minh

+0

Btw、なぜ私はサービスを実行するたびにシーケンスをリセットすると思います(データベースにデータをフェッチする)、ユニークな識別子が1増加しました。たとえば、初めてデータを実行すると、IDは1から始まり10で終わります2回目にデータを実行すると、idは11で始まり、20で終わります。この問題は、サーバーを再起動するときにのみ停止します。 – minh

+0

ありがとう、私は解決策を発見した、createNativeQuery()は、シーケンスを作成するために使用することができます。 – minh

関連する問題