9

@SqlResultSetMapping の @ConstructorResult を使用しているときに @ColumnResult タイプで Enum を使用する方法がわかりません

@SqlResultSetMapping(name="DetailAndResult",
        classes={
                @ConstructorResult(targetClass=DetailAndResult.class, columns={
                        @ColumnResult(name="id", type= String.class),
                        @ColumnResult(name="runId", type=Integer.class),
                        @ColumnResult(name="subRunId", type=Integer.class),
                        @ColumnResult(name="transactionId", type=Integer.class),
                        @ColumnResult(name="referenceNumber", type=String.class),
                        @ColumnResult(name="customerName", type=String.class),
                        @ColumnResult(name="transactionType", type=TransactionType.class),
                        @ColumnResult(name="transactionResultStatus", type=String.class)

                })
        }
)

上記の構成では、名前「transactionType」は TransactionType Enum です。ここで Enum を使用する正しい方法は何ですか。

上記が正しい方法である場合、この例外が発生します(Enumフィールドを削除すると例外はありません)ので、これを使用する別の方法があるはずだと考えています。

Caused by: javax.persistence.PersistenceException: org.hibernate.type.SerializationException: could not deserialize
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763) ~[hibernate-entitymanager-4.3.6.Final.jar:4.3.6.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677) ~[hibernate-entitymanager-4.3.6.Final.jar:4.3.6.Final]
    at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:458) ~[hibernate-entitymanager-4.3.6.Final.jar:4.3.6.Final]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_51]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_51]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_51]
    at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_51]
    at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:333) ~[spring-orm-4.0.5.RELEASE.jar:4.0.5.RELEASE]
    at com.sun.proxy.$Proxy146.getResultList(Unknown Source) ~[na:na]

hibernateTemplate では、sqlquery.addscalar を使用していましたが、org.hibernate.type.Type を使用して Enum を使用する方法がありました。

TypeLocatorImpl(new TypeResolver()).custom(EnumType.class, params)

このようなものが @SqlResultSetMapping と @ConstructorResult に使用されるかどうか提案してください

4

3 に答える 3

12

私もこの問題に遭遇しましたが、かなり広範囲に検索しても何も見つかりませんでした。私はソースコードを見ている限り行ってきました.enumの処理はまったくありませんでした.

私がやったのは、列挙型の文字列を取り、それを列挙型の valueOf() メソッドに渡す代替コンストラクターを作成することでした。

例えば

@SqlResultSetMapping を変更してこれを行います。

@ColumnResult(name="transactionType", type=String.class),

そして、クラスのコンストラクターで:

public DetailAndResult(..., String transactionType, ...) {
    ...
    this.transactionType = TransactionType.valueOf(transactionType);
    ...
}

これを行わなければならないのは面倒ですが、列挙型がデータベースに文字列として格納されている限り (つまり、エンティティの列に @Enumerated(EnumType.STRING) の注釈が付けられている場合)、機能します。

于 2015-10-29T12:29:07.353 に答える
1

この文書化されていない解決策に出くわしました。の型には、コンストラクターが期待する型の型をマップ@ColumnResult する休止状態のUserTypeを配置できます。これは休止状態で機能し、他の JPA 実装がこれをサポートするかどうかはわかりません。

したがって、あなたの例では、列挙型のカスタム UserType を実装し、そのクラスを@ColumnResult.

于 2014-12-03T08:17:43.440 に答える