I have an unknown JPA entity and need to know it's version. I could not find a way to do this generically.
I tried the metamodel, but don't know what to pass to getVersion() method:
Object entity = ...;
Metamodel metamodel = entityManager.getMetamodel();
IdentifiableType<?> metaClass =
(IdentifiableType<?>)metamodel.managedType(entity.getClass());
metaClass.getVersion(<what to put here?>);
Same pattern is used in metaClass.getId()
, but there is a complementary method getIdType()
-- getVersionType()
is missing.
Secondly, there is entityManagerFactory.getPersistenceUnitUtil().getIdentifier(entity)
method, but not getVersion(entity)
method.
Is there some way to get version from an unknown entity?
I solved it in the following way: The javax.persistence.Version
class specifies supported datatypes, only seven are supported, so I try all of them one after other. The JPA spec apparently misses the getVersionType()
method, I think it is a bug.
/**
* Finds the version attribute for ManagedType instance.
* @param managedType The metaobject
* @return The version attribute or null, if it does not have one
* @throws UnsupportedOperationException
* If it has a version attribute, but is not one of supported types, as specified in {@link Version} documentation
* (currently int, Integer, short, Short, long, Long, Timestamp).
*/
private static <T> SingularAttribute<? super T, ?> findVersionAttribute(ManagedType<T> managedType) {
if ( !(managedType instanceof IdentifiableType))
return null;
IdentifiableType<T> identifiableType = (IdentifiableType<T>)managedType;
if ( ! identifiableType.hasVersionAttribute())
return null;
try {
return identifiableType.getVersion(int.class);
} catch (IllegalArgumentException e) {
try {
return identifiableType.getVersion(Integer.class);
} catch (IllegalArgumentException e1) {
try {
return identifiableType.getVersion(long.class);
} catch (IllegalArgumentException e2) {
try {
return identifiableType.getVersion(Long.class);
} catch (IllegalArgumentException e3) {
try {
return identifiableType.getVersion(short.class);
} catch (IllegalArgumentException e4) {
try {
return identifiableType.getVersion(Short.class);
} catch (IllegalArgumentException e5) {
try {
return identifiableType.getVersion(Timestamp.class);
} catch (IllegalArgumentException e6) {
throw new UnsupportedOperationException("The version attribute is not of supported type");
}
}
}
}
}
}
}
}