Announcement Announcement Module
Collapse
No announcement yet.
DAO for abstract class: Cannot instantiate abstract class or interface Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • DAO for abstract class: Cannot instantiate abstract class or interface

    Hi everyone.

    Till today I have done my projects always and completely with Roo, but now I'm starting to use it only for handle getters and setters creation (@RooJavaBean).

    So I have to handle the DAOs myself.

    My problem is explained below:

    I have an abstract class VerbaleMt, extended by an abstract class VerbaleMtB, extended by a class VerbaleMtBTT.

    Code:
    @RooJavaBean 
    @Entity
    @Table(name="ext_verbale_MT")
    @Inheritance(strategy=javax.persistence.InheritanceType.JOINED)
    public abstract class VerbaleMt implements DomainObject { 
    ....
    }
    
    @RooJavaBean
    @Entity
    @Inheritance(strategy=javax.persistence.InheritanceType.JOINED)
    @Table(name="ext_verbale_MT_B")
    public abstract class VerbaleMtB extends VerbaleMt implements DomainObject {
    ...
    }
    
    
    @RooJavaBean
    @Inheritance(strategy=javax.persistence.InheritanceType.JOINED)
    @Table(name="ext_verbale_MT_B_TT")
    @Entity
    public class VerbaleMtBTT extends VerbaleMtB{
    ....
    }

    So here is my dao interface and implementation

    Code:
    public interface GenericDao <T extends DomainObject> {
    	
    	public T get(Long id);
    	
    	public List<T> getAll();
    	
    	public void save(T object);	
    	
    	public void delete (T object);
    	
    }
    
    public class GenericDaoJpa<T extends DomainObject> implements GenericDao<T> {
    
        private Class<T> type;
    
        @PersistenceContext
        protected EntityManager entityManager;
    
        public GenericDaoJpa(Class<T> type) {
            super();
            this.type = type;
        }
     
        public T get(Long id) {
            return (T) entityManager.find(type, id);
        }
    
        public List<T> getAll() {
        	Query query = entityManager.createQuery("select obj from " + type.getName() + " obj"); 
        	return query.getResultList();
        }
    
        public void save(T object) throws DataAccessException {
            entityManager.persist(object);
        }
    
        public void delete(T object) throws DataAccessException {
            entityManager.remove(object);
        }
    }
    Observing what Roo do, I've implemented the DAO for the first abstract class inherited: VerbaleMt.

    Code:
    @Repository("verbaleMtDao")
    public class VerbaleMtDaoJpa extends GenericDaoJpa<VerbaleMt> implements VerbaleMtDao {
    
        public VerbaleMtDaoJpa() {
            super(VerbaleMt.class);
        } 
    
    }
    I've also configured "verbaleMtDao" used by @Repository annotation.

    In testing phase all goes right except one thing! I can insert and remove instances of VerbaleMtBTT from my DB.. but I cannot list elements.

    Code:
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = { "classpath:/META-INF/spring/spring-master.xml" })
    @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
    @Transactional
    public class VerbaleMtBTTDaoTest {
    	
    	
    	VerbaleMtBTT verbaleMtBTT;
    	
    	@Autowired
    	VerbaleMtDao verbaleMtDao;
    	
    	
    	@Before
    	public void initializeTest(){
    		verbaleMtBTT = new VerbaleMtBTT();
    		
    		verbaleMtBTT.setAnnoimp((short)2010);
    		verbaleMtBTT.setCondnudiso("Isolato");
    		
    		verbaleMtDao.save(verbaleMtBTT);
    	}
    	
    	@After
    	public void finalizeTest(){
    		verbaleMtDao.delete(verbaleMtBTT);
    		verbaleMtDao = null;
    	}
    	
    	@Test
    	public void testMessagePersisted(){
    	--->>	final List<VerbaleMt> messaggi = verbaleMtDao.getAll();
    		Assert.assertTrue(messaggi.size() > 1);		
    	}
    }

    When I call verbaleMtDao.getAll(); it throws an exception:

    Code:
    org.springframework.orm.jpa.JpaSystemException: org.hibernate.InstantiationException: Cannot instantiate abstract class or interface: it.cpmapave.mt.verbali.domain.VerbaleMtB; nested exception is javax.persistence.PersistenceException: org.hibernate.InstantiationException: Cannot instantiate abstract class or interface: it.cpmapave.mt.verbali.domain.VerbaleMtB
    	at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:311)
    	at org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect.ajc$afterThrowing$org_springframework_orm_jpa_aspectj_JpaExceptionTranslatorAspect$1$18a1ac9(JpaExceptionTranslatorAspect.aj:15)
    	at it.cpmapave.mt.verbali.dao.jpa.GenericDaoJpa.getAll(GenericDaoJpa.java:35)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    	at $Proxy26.getAll(Unknown Source)
    	at .......
    Surely it is an error of mine.. but I don't find where..

    can someone please give me a help?

    Thank you
    Marco

  • #2
    An abstract class cannot be an entity, it can only be a @MappedSuperclass... Also why do you want/need daos for the abstract types?! IMHO that doesn't make sense.

    Comment


    • #3
      Thank you for your answer!

      I look at what Roo produce... and when I create an abstract entity it add @RooEntity annotation at class level, even if it is abstract. This is because of @Entity annotation in an abstract class.

      And looking in the aspects generated by the annotation, Roo inject the EntityManager only in the first inherited abstract class.

      So given:

      1)abstract classA

      2)abstract classB extend classA

      3)classC extend classB

      It put
      Code:
      @PersistenceContext
      transient EntityManager entityManager;
      only in classA.

      Also persist, delete, merge method are only in classA.. but probably this because this methods are as if they were in the Entity class cause of Aj, and then inherithed in the others.

      So you tell me that I have to remove the Entity annotation from abstract class.. I tried to remove it.. but the hibernate validation ddl now give me an exception:

      Code:
      No identifier specified for entity: it.cpmapave.mt.verbali.domain.VerbaleMtBTT
      And it is true.. My key field is only in the first inherited abstract class, say in ClassA.

      So not removing @Entity and putting annotation

      Code:
      @Inheritance(strategy=javax.persistence.InheritanceType.JOINED)
      it put in relation the db tables by the "ID" key field inherited by first abstract class in which i declared it.


      I have to start from a given schema.. and I'm trying do creade POJOs around it.. May I have do something wrong in mapping DB entity to POJOs?

      But all work fine.. except the list method..


      So I need only DAOs for non abstract class as you say. Infact list in DAO for VerbaleMtTTB works fine!

      Marco

      Comment


      • #4
        You shouldn't remove the @Entity you should replace it with @MappedSuperclass (as I stated in my previous post). (I suggest a read on jpa and the different annotations especially in the case of subclasses).

        Comment


        • #5
          Reading @MappedSuperclass doc I found on the first lines:

          A mapped superclass has no separate table defined for it. A class designated with the MappedSuperclass annotation can be mapped in the same way as an entity except that the mappings will apply only to its subclasses since no table exists for the mapped superclass itself.
          But my db has a table for each abstract class.. So I cannot use @MappedSuperclass. I instead use

          Code:
          @Inheritance(strategy=javax.persistence.InheritanceType.JOINED)
          to map each table referred by abstract class.

          Only the "last table" of the hierarchy correspond a non abstract class..

          did you think there is something wrong?

          Comment


          • #6
            Hmm... After some googling the only thing I see is that @Entity with @Inheritance on each of the classes should work. You don't need a dao for all of these abstractclasses, only for the concrete implementations, so I suspect that is where you went wrong (and I learned something again about @MappedSuperclass)

            Comment


            • #7
              Ok, thanks.

              You have been very kind to devote your time!

              Marco

              Comment

              Working...
              X