I am trying to implement the following diagram in Hibernate, JPA.
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;
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With