Open kasimmm opened 7 years ago
This seems to be a Hibernate error. Usually enums passed through Jinq work fine with Hibernate, so I'm not sure what the issue might be. Do you have more detailed error information from Hibernate? What did Hibernate say was the expected type and what did it think it received?
It said something like this
java.lang.IllegalArgumentException: Parameter value [PENDING] did not match expected type [com.abc.model.AuthKey$Status (n/a)]
at org.jinq.jpa.JPAQueryComposer.fillQueryParameters(JPAQueryComposer.java:127)
at org.jinq.jpa.JPAQueryComposer.executeAndReturnResultIterator(JPAQueryComposer.java:167)
at org.jinq.orm.stream.QueryJinqStream.createWrappedStream(QueryJinqStream.java:37)
at org.jinq.orm.stream.LazyWrappedStream.realizeStream(LazyWrappedStream.java:41)
at org.jinq.orm.stream.LazyWrappedStream.collect(LazyWrappedStream.java:227)
at org.jinq.orm.stream.NonQueryJinqStream.toList(NonQueryJinqStream.java:492)
I checked in the lambda expression, both the k.getStatus() and s are with Enum type.
I also tried fetching a record without the where clause then compared it with the parameter like
result(0).getStatus() == s
and it actually returned true.
That seems strange. What happens when you move the Status enum to be its own top-level class instead of an inner-class? That's the only difference that I can see from my own test cases.
Maybe making the Status enum static
would work too?
Hmmmm still no luck with making it the top-level enum class. Ahhh just realised I forgot to mention that the parameter was actually passed from another service like this:
authKeyService.getAuthKey(Status.PENDING);
then in this AuthKeyService:
public AuthKey getAuthKey(Provider provider) throws AuthKeyServiceException {
List<AuthKey> authKeys = streamAll(em, AuthKey.class).where(k -> k.getProvider() == provider).toList();
........
}
Maybe it is the reason?
That should be fine. But there might be a classloader issue. Have you looked at this Stack Overflow about Hibernate and enums?
http://stackoverflow.com/questions/27622045/parameter-value-did-not-match-expected-type
If that still doesn't work, you could try just dropping down to raw JPA/Hibernate there and seeing if the problem still comes up.
em.createQuery("SELECT * FROM AuthKey a WHERE a.status = :param")
.setParameter("param", s)
.getResultList()
It's seems like a strange Hibernate issue, so I'm just suggesting random ideas. What happens if you move the @Enumerated(EnumType.STRING)
annotation onto the getter instead of the field? What happens if you make the status
field public instead of private?
@my2iu all the enums are static!, even if they are nested.
I am using code like the one you provided @kasimmm with hibernate 5.2 with no issue.
@my2iu
@aVolpe I'm having some trouble switching to 5.2 (we are using 4.3) at the moment. Will definitely give it a try later.
Anyway, thank you both for your time and help :)
If the raw JPA seems to work, then I don't know what the issue could be because that should be exactly the same code that Jinq is running.
The Stack Overflow solution is actually at the end of the page (it's not the first one listed). The accepted solution says there might be a classloader problem because of the way things are packaged up (it's possible to have two classes with the same name which Java thinks are different because they were loaded in different class loaders). But if the raw JPA worked for you, then that shouldn't be an issue.
I don't think I'll be able to help you further with this without some sample code that exhibits the problem that I can run and debug.
@my2iu Sorry for the late reply. I tried to replicate it with some sample code using same libs (hibernate-4.3.11, hibernate-jpa-2.0.1, etc.) but it worked just fine. The only difference is that our application runs as a spring boot application, which shouldn't really matter in this case. I'm using the raw JPA as a solution for now and will try to setup another env (spring boot/mysql) if I have some time.
@aVolpe Turns out that hibernate version isn't the issue as I was using the same version with some sample code and it worked fine.
Cheers.
I don't know if this was the case for kasimmm, but I have encountered similar issue. The problem was that we had spring devtools in dependencies of our project, so what it does is it loads all third-party libraries with default ClassLoader, but all project classes with a separate ClassLoader. Removing devtools from dependencies solved the issue
@OknoLombarda you saved me. I spent 3+ hours debugging this, and your comment fixed it!
Hi, I have a model with an enum property like this:
The enum field is persisted in MySQL as varchar.
When I do a search like
streamAll(em, AuthKey.class).where(k->k.getStatus() == Status.PENDING)
it works just fine.But when I do a search using a parameter
it complains that 'Parameter value did not match expected type'
Any idea why? Thanks