Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Incompatible data types in combination" leading to "Could not initialize a collection" in JPA with an inherited bidirectional relation

I am trying to implement the following diagram in Hibernate, JPA.

enter image description here

I tried to implement it this way.

For the farm

@Entity
public class Farm implements Serializable{

    @OneToMany(mappedBy = "farm", cascade = { CascadeType.ALL }, targetEntity=AbstractAnimals.class, fetch=FetchType.LAZY)
    private List<AbstractAnimal> animals = new ArrayList<AbstractAnimals>();

}

For the Abstract Annimal

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractAnimal implements Serializable{
    @Id
    private int id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "farmId", nullable = false)
    private Farm farm;

    ... other attributes and getter and setter
}

For the Abstract Mammalian

@MappedSuperClass
public abstract class AbstractMammalian extends AbstractAnimal implements Serializable{
    ... other attributes and getter and setter
}

For all the annimals

@Entity
public abstract class 'Animal' extends 'supertype' implements Serializable{

    ... other attributes and getter and setter
}

When I tried to get all the farm animals I get the following error

org.hibernate.exception.SQLGrammarException: could not initialize a collection: [my.example.Farm.animals#24]
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.loader.Loader.loadCollection(Loader.java:2173)
    at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:62)
    at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:627)
    at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:83)
    at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1863)
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:369)
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
    at org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:272)
    at my.example.persistence.Farm.getAnnimals(Farm.java:132)
    at my.example.DTOFactory.updateFarmDTO(DTOFactory.java:269)
    at my.example.DTOFactory.createFarmDTO(DTOFactory.java:250)
    at my.example.DTOFactory.createChickenDTO(DTOFactory.java:183)
    at my.example.ChickenServiceImpl.createChicken(ChickenServiceImpl.java:62)
    at my.example.ChickenServiceTest.createChickenWithHome(ChickenServiceTest.java:243)
    at my.example.ChickenServiceTest.testRejectChickenHome(ChickenServiceTest.java:186)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.sql.SQLSyntaxErrorException: incompatible data types in combination
    at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
    at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source)
    at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source)
    at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:534)
    at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:452)
    at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:161)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1700)
    at org.hibernate.loader.Loader.doQuery(Loader.java:801)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
    at org.hibernate.loader.Loader.loadCollection(Loader.java:2166)
    ... 40 more
Caused by: org.hsqldb.HsqlException: incompatible data types in combination
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.types.BitType.getAggregateType(Unknown Source)
    at org.hsqldb.types.Type.getAggregateType(Unknown Source)
    at org.hsqldb.QuerySpecification.resolveTypesPartOne(Unknown Source)
    at org.hsqldb.QueryExpression.resolveTypesPartOne(Unknown Source)
    at org.hsqldb.QueryExpression.resolveTypes(Unknown Source)
    at org.hsqldb.ParserDQL.XreadTableSubqueryOrNull(Unknown Source)
    at org.hsqldb.ParserDQL.readTableOrSubquery(Unknown Source)
    at org.hsqldb.ParserDQL.XreadTableReference(Unknown Source)
    at org.hsqldb.ParserDQL.XreadFromClause(Unknown Source)
    at org.hsqldb.ParserDQL.XreadTableExpression(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQuerySpecification(Unknown Source)
    at org.hsqldb.ParserDQL.XreadSimpleTable(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryPrimary(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryTerm(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryExpressionBody(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryExpression(Unknown Source)
    at org.hsqldb.ParserDQL.compileCursorSpecification(Unknown Source)
    at org.hsqldb.ParserCommand.compilePart(Unknown Source)
    at org.hsqldb.ParserCommand.compileStatement(Unknown Source)
    at org.hsqldb.Session.compileStatement(Unknown Source)
    at org.hsqldb.StatementManager.compile(Unknown Source)
    at org.hsqldb.Session.execute(Unknown Source)
    ... 49 more

Edit

EntityManager manager = null;
EntityTransaction tx = null;
TaskDTO result = null;

try {
    manager = PersistenceUtils.getEntityManager();
    try
    {
       tx = manager.getTransaction();
       tx.begin();
       Farm farm = manager.find(Farm.class, 
       Farmer farmer = manager.find(farmer.class, farmerDtoID);
       int status = AnimalService.IDLE;

       if (birth.before(new Date())){
           status = TaskService.UNBORN;
       }
       Chicken newChicken = new Chicken(name, farm, user, birth, death, status);
       manager.persist(newChicken);
       tx.commit();
       result = DTOFactory.createChickenDTO(newChicken, true);
   }
   finally
   {
       if (tx.isActive())
       {
           tx.rollback();
       }
   }
}
finally
{
    if (manager != null)
    {
        manager.close();
    }
 }
 return result;
like image 872
Baptiste Gousset Avatar asked Nov 14 '22 01:11

Baptiste Gousset


1 Answers

I have no idea what you're doing wrong. You just haven't shown us enough code to detect the problem.

Here is how you can do it right:

  • https://bitbucket.org/twic/farm/src

That is an implementation of the same object model, but in a way which works fine. There is a Gradle script which will generate and apply the relevant SQL; you can then run the Main class to insert and query some data, including calling Farm.getAnimals().

There are a few differences between my code and yours. Mine is simpler; i have left out the various unnecessary things like specifying column names, explicitly stating that collections are lazy, making entity classes serializable, etc. I have also opted to annotate AbstractMammal as an @Entity, not a @MappedSuperclass. I saw no reason not to. I tried it both ways, and both ways worked.

So, whatever it is that's going wrong for you, it is a difference between your code and mine. It could be a bug in your JPA implementation. It is more likely to be a bug in your annotations. I suggest you clone my code, make it run, then start modifying it bit by bit to be more like your code, and see when it breaks.

like image 75
Tom Anderson Avatar answered Dec 29 '22 14:12

Tom Anderson