Class cannot be added to java.lang.reflect.ParameterizedType

VariableService is @Autowired located @Autowired in my controller.

I understand that I can implement the ParameterizedType class so that this error disappears, but I'm afraid that I might go in the wrong direction. Is there a better way to do this or do I need to bite a bullet and implement ParameterizedType methods?

org.springframework.beans.factory.BeanCreationException: an error occurred while creating a bean named "contentController": the injection of autodetected dependencies failed; The nested exception is org.springframework.beans.factory.BeanCreationException: Failed to auto-field field: private com.fettergroup.cmt.service.VariableService com.fettergroup.cmt.web.ContentController.variableService; The nested exception is org.springframework.beans.factory.BeanCreationException: an error occurred while creating a bean with the name "variableService" defined in the ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: bean activation failed; The nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate bean class [com.fettergroup.cmt.service.VariableService]: constructor made an exception; The nested exception is java.lang.ClassCastException: java.lang.Class cannot be attributed to java.lang.reflect.ParameterizedType

Service variable

 public class VariableService extends EntityService { public VariableService () { super.setEntityRepository(new VariableRepository()); } } 

EntityService

 public abstract class EntityService<T> { public EntityRepository<T> entityRepository; public T create(T entity) { return entityRepository.create(entity); } public T update(T entity) { return entityRepository.update(entity); } public void delete(T entity) { entityRepository.delete(entity); } public void setEntityRepository(EntityRepository<T> entityRepository) { this.entityRepository = entityRepository; } } 

Variable repository

 public class VariableRepository extends EntityRepository { } 

EntityRepository

 @Repository public abstract class EntityRepository<T> { //the equivalent of User.class protected Class<T> entityClass; @PersistenceContext(type= PersistenceContextType.TRANSACTION) public EntityManager entityManager; public EntityRepository () { //Get "T" and assign it to this.entityClass ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass(); this.entityClass = (Class<T>) genericSuperclass.getActualTypeArguments()[0]; } /** * Create this entity * @param t * @return */ public T create(T t) { entityManager.persist(t); return t; } /** * Update this entity * @param t * @return */ public T update(T t) { return entityManager.merge(t); } /** * Delete this entity * @param entity */ public void delete(T t) { t = this.update(t); entityManager.remove(t); } public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } } 
+9
java spring-mvc
source share
4 answers

Simply put, this is a pretty bad design for determining the type of entity. You should do the following, instead of relying on reflection, to draw the conclusion of your class. Not only will he get rid of this error, but he will be generally cleaner and at a lower level, faster than reflection (and not that it really will be a problem).

 @Repository public abstract class EntityRepository<T>{ protected Class<T> entityClass; public EntityRepository(Class<T> entityClass){ this.entityClass = entityClass; } //... } public class UserEntityRepository extends EntityRepository<User>{ public UserEntityRepository(){ super(User.class); } } 
+14
source share

EntityRepository is not a parameterized type of type. This class extends ParameterizedType. It is also possible if spring proxied you with the cglib class

We need to check the parents of the class.

 public EntityRepository () { //Get "T" and assign it to this.entityClass Type genericSuperClass = getClass().getGenericSuperclass(); ParameterizedType parametrizedType = null; while (parametrizedType == null) { if ((genericSuperClass instanceof ParameterizedType)) { parametrizedType = (ParameterizedType) genericSuperClass; } else { genericSuperClass = ((Class<?>) genericSuperClass).getGenericSuperclass(); } } entityClass = (Class<T>) parametrizedType.getActualTypeArguments()[0]; } 
+6
source share

You seem to be abusing ParameterizedType . In the EntityRepository constructor EntityRepository you should use something like the following, with appropriate checks.

 public EntityRepository () { //Get "T" and assign it to this.entityClass ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass(); Type type = genericSuperclass.getActualTypeArguments()[0]; if (type instanceof Class) { this.entityClass = (Class<T>) type; } else if (type instanceof ParameterizedType) { this.entityClass = (Class<T>) ((ParameterizedType)type).getRawType(); } } 

This implementation is far from complete, since you must also handle GenericArrayType values ​​as well as nested ParameterizedType .

+2
source share

@ The reposition annotation must be removed from the EntityRepository class to solve the problem.

Read this topic

java.lang.Class cannot be added to java.lang.reflect.ParameterizedType

+1
source share

All Articles