0

Good Morning,

I am building a web application and I chose to do it with an annotation driven spring mvc with REST Webservices (Jackson).

I am not using spring-boot because I wanted to add the libraries gradually when I needed them.

When I try to reach my specific repository with String str = ((GroupeMaterielRepository) repository).test(); i get a

java.lang.ClassCastException: com.sun.proxy.$Proxy210 cannot be cast to pro.logikal.gestsoft.repository.GroupeMaterielRepository]

I would like to know how to access to my specific repository methods in which my HQL requests would be stored. I am trying to find a solution for days without success. The best I could do so far was accessing my CRUD methods in the generic repository implementation, but this implies to store in my repository interface every HQL method in the app, which will result as ugly.

I would like you to help me to get this code to work, keeping the logic of autowiring through interface's implementations extended by a more specific class with a controller layer and a repository layer.

Generic Controller :

package pro.logikal.gestsoft.controller;

import pro.logikal.gestsoft.repository.GenericCRUD;

public class GenericRestController<T> {

    protected GenericCRUD<T> repository;

    public GenericRestController(GenericCRUD<T> repository) {
        this.repository = repository;
    }

    public GenericCRUD<T> getRepository() {
        return repository;
    }



}

Specific Controller :

package pro.logikal.gestsoft.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import pro.logikal.gestsoft.entity.GroupeMateriel;
import pro.logikal.gestsoft.repository.GenericCRUD;
import pro.logikal.gestsoft.repository.GroupeMaterielRepository;

@RestController
public class MaterielRESTController extends GenericRestController<GroupeMateriel> {


    @Autowired
    public MaterielRESTController(GenericCRUD<GroupeMateriel> repository) {
        super(repository);
        // TODO Auto-generated constructor stub
    }


    @GetMapping("/mat/groupes")
    public ResponseEntity<String> getGroupes(){

        String str = ((GroupeMaterielRepository) repository).test();

        return new ResponseEntity<String>(str, HttpStatus.OK);
    }



}

Repository Interface :

package pro.logikal.gestsoft.repository;

import java.util.List;

public interface GenericCRUD<T> {

    void create(T entity);

    void update(T entity);

    void refresh(T entity);

    void delete(Integer id);

    T find (Integer id);

    List<T> list();

}

Repository implementation :

package pro.logikal.gestsoft.repository;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.annotation.Transactional;

import pro.logikal.gestsoft.statics.ClientRequestUtils;
import pro.logikal.gestsoft.statics.DatabaseUtils;

@SuppressWarnings("unchecked")
@Transactional(DatabaseUtils.TM_GESTSOFT)
public class GenericCRUDImpl<T> implements GenericCRUD<T> {


    @SuppressWarnings("unused")
    public final Class<T> persistentClass;

    @Autowired
    @Qualifier(DatabaseUtils.GESTSOFT_SESSION)
    public SessionFactory sessionFactory;

    protected Session getCurrentSession() {
        Session session = sessionFactory.getCurrentSession();
        return session;
    }

    public GenericCRUDImpl(){
        this.persistentClass= (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }


    @Override
    public void create(final T entity) {
        this.getCurrentSession().save(entity);

    }

    @Override
    public void update(final T entity) {
        this.getCurrentSession().update(entity);

    }

    @Override
    public void refresh(final T entity) {
        this.getCurrentSession().refresh(entity);

    }

    @Override
    public void delete(Integer id) {
        this.getCurrentSession().delete(this.find(id));

    }

    @Override
    public T find(Integer id) {
        // TODO Auto-generated method stub
        return this.getCurrentSession().get(persistentClass, id);
    }


    @Override
    public List<T> list() {
        return this.getCurrentSession().createQuery("from "+persistentClass.getTypeName()).getResultList();
    }

}

Repository associated to an entity and which is meant to contain the HQL requests for the related entities :

package pro.logikal.gestsoft.repository;

import org.springframework.stereotype.Repository;

import pro.logikal.gestsoft.entity.GroupeMateriel;

@Repository
public class GroupeMaterielRepository extends GenericCRUDImpl<GroupeMateriel> {


    public String test() {
        return "ok";
    }

}
Philippe Merle
  • 115
  • 2
  • 4
  • 13
  • Define a sub-interface with the test method, and inject that. Or don't define an interface, and inject GroupeMaterielRepository. If you inject a GenericCRUD, that means you only care about the methods defined in GenericCRUD. – JB Nizet Nov 23 '18 at 22:11
  • Note that spring-data-jpa provides all this base repository implementation, and much more, for you. And it uses it without using the proprietary Hibernate API. – JB Nizet Nov 23 '18 at 22:13

1 Answers1

0

Just found out from where my problem came from reading [https://stackoverflow.com/a/6512431/8822802][1]

in my case @EnableAspectJAutoProxy(proxyTargetClass = true) on my config file

Philippe Merle
  • 115
  • 2
  • 4
  • 13