问题
I am not having any idea how to use Enum in @ColumnResult Type while using @ConstructorResult of @SqlResultSetMapping
@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)
})
}
)
in above configuration, name 'transactionType' is of TransactionType Enum. What is the correct way to use Enum here.
if above is the correct way then I am getting this exception (If I will remove the Enum field then there is no exception) so thinking that there should be another way to use this.
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]
With hibernateTemplate, we were using sqlquery.addscalar and there was a way to use Enum there using org.hibernate.type.Type and
TypeLocatorImpl(new TypeResolver()).custom(EnumType.class, params)
Please suggest if something like this will be used for @SqlResultSetMapping and @ConstructorResult
回答1:
I've also run into this problem and haven't found anything after a fairly extensive search. I've gone as far as looking at the source code, and as far as I could tell there wasn't any kind of handling for enums at all (although of course I could be missing something).
What I ended up doing was creating an alternative constructor that took in a String for the enum type, and then passed it into the enum's valueOf() method.
E.g.
change your @SqlResultSetMapping to do this:
@ColumnResult(name="transactionType", type=String.class),
And then in the constructor of your class:
public DetailAndResult(..., String transactionType, ...) {
...
this.transactionType = TransactionType.valueOf(transactionType);
...
}
It's annoying that we have to do this, but so long as your enum is stored as a String in the db (i.e. the column on your entity is annotated with @Enumerated(EnumType.STRING)), it works.
回答2:
Came across a undocument solution for this one. In the type of the @ColumnResult
you can place a hibernate UserType that maps the type in type the constructor is expecting. This works for hibernate and i am unsure if other JPA implementations would support this.
So in you example you would implement a custom UserType for enums and put that class in the @ColumnResult
.
来源:https://stackoverflow.com/questions/25738728/constructorresult-with-enum-in-jpa-2-1