2012-04-04 22 views
2

のOpenJPA 1.2.2は、WebSphere 7(のJava EE 5)OpenJPAの - 不可解な例外が名前付きネイティブクエリ

を作成し、私はPOJOにテーブルをマップしようとしているnamed-を使用して(未実体!) orm.xmlで定義されたネイティブクエリ:

<named-native-query name="myNativeQuery" result-class="foo.bar.PojoBean"> 
    <query> 
     SELECT col_one AS colOne, col_two AS colTwo, col_three AS colThree 
     FROM myTable WHERE id = 42 
    </query> 
</named-native-query> 

PojoBeanがStringゲッター/セッターと空の引数のコンストラクタでfinalクラスである:私は、クエリを作成すると

public final class PojoBean implements java.io.Serializable { 

    public PojoBean() { 
    } 

    public String getColOne() { ... } 
    public void setColOne(String colOne) { ... } 
    ... 
} 

EntityManager myEntityManager = ... 
myEntityManager.createNamedQuery("myNativeQuery"); 

私は(読みやすくするためにフォーマット済み)は例外だ:それは意味しない何

<openjpa-1.2.2-r422266:898935 nonfatal user error> 
org.apache.openjpa.persistence.ArgumentException: 
Result type "class foo.bar.PojoBean" does not have any public fields or setter methods for the projection or aggregate result element "null", 
nor does it have a generic put(Object,Object) method that can be used, 
nor does it have a public constructor that takes the types null. 

を?

詳細情報:

  • PojoBeanの実装を変更することはできません、最終的なクラスとしても拡張することはできません。
  • EntityManager.createNativeQuery(...)を使用してjavaからクエリを実行すると機能しますが、オプションではありません。

あなたが展開されたJARのクラスPojoBeanが実際に&ゲッター公共セッターを持っていることを確認することがあり、

+0

あなたは不安定なセッターを持っていますか? setValue(String val)setVatue(Integer val)のようなものです。あなたの問い合わせがnullを返す場合は、それがabigiuosかもしれません。setterは呼び出されるべきです。 –

+0

あいまいなセッターはありません。 orm.xmlを使用する代わりにJava(EntityManager.createNativeQuery(...))でクエリをコーディングすると動作します。 – Giambo

+0

ジグルについては、あなたのPOJOを最終的なものにしてみることができますか?また、ormスニペットは、問合せがネイティブ問合せであることを示します。なぜ、createNativeQuery(...)をコールしていないのですか。 – Rick

答えて

0

、ありがとうございました。

+0

Getter/Settersはpublicです。例外に示唆されているように私が手作業で「put(Object、Object)」メソッドを追加しても動作するようですが、この解決策は受け入れられません。 – Giambo

+0

Beanでプリミティブ(int、longなど)を使用していないことを確認できますか? JPAは、投影または集約結果要素 "null"のnull-'を設定する問題に直面している可能性があります。 –

+0

Beanはプリミティブなしで、BeanはStringのみを使用します。また、データベース(Oracle)の列はVARCHAR2として定義されています。 – Giambo

0

私も同じ例外があります。私の場合の問題は、persistence.xmlの永続性ユニット名が間違っていたことです。この場合、excpetionは、

0

問題は、OpenJPAのがcameCaseNameにない自動マップunderscore_namesを行うということです...正しい方向に正確にポイントあなたはがあなたのPOJOを満たすために翻訳するために提供する必要がありそうありません。

あなたのケースでは、col_one => colOneですが、openJPAはそれを認識しません。

public void put(Object field, Object value) { 

    try { 

     String fieldName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, field.toString()); 
     Field f = this.getClass().getDeclaredField(fieldName); 
     f.set(this, value); 

    } 
    catch(Exception e) { 
     logger.error("ERROR: " + e.getMessage()); 
    } 

} 

私はこれが好きではないと言わなければならない:私は何

は、文字列の変換のためのGoogle Guavaから少し助けを借りて、リフレクションを介して対応するフィールドに値を代入し、一般的なセッターを実装することでした解決策は非常に多いですが、実際にはうまくいきます。いくつかのインターフェースを実装する方法や@Annotationを使ってこれを配線する方法はありますか?

別の方法は、すべてのpojoが拡張する抽象クラスです。その場合、フィールドはプライベートである可能性があるため、セッターメソッドを使用する必要があります。

public abstract class JpaPutter { 


    public void put(Object field, Object value) { 

     try { 

      String methodName = "set" + CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, field.toString()); 
      this.getClass().getMethod(methodName, value.getClass()).invoke(this, value); 

     } 
     catch(Exception e) { 
      throw new RuntimeException(e); 
     } 

    } 
} 
関連する問題