-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Nullable data using inheritance in same table (annotations)
PostPosted: Fri Apr 03, 2009 4:34 pm 
Newbie

Joined: Fri Apr 03, 2009 4:12 pm
Posts: 9
Hibernate version: 3.2
Code between sessionFactory.openSession() and session.close():
Name and version of the database you are using:oracle 9i

Hello,

I have a supperclass that is extended by two classes and I wish to map them to the same table (using annotations).

My problem is that subclass A needs some data to be non null and subclass B doesnt have this data at all:

Subclass B:
Code:

@Column( name = "cd_error", nullable = false, length=100)
   public String getError() {
      return error;
   }

   public void setError(String error) {
      this.error = error;
   }


So, when i try to persist a Subclass B object I get an error complaining about cd_error being null:
cannot insert NULL into ("xxxx"."yyyy"."CD_ERROR")

I suppose I can set a default value to cd_error when using subclass A, or even set cd_error to nullable. But I really dont like this solutions.

Im testing this using JUnit 4.

Is there anyway to fix this problem?
Thanks for your help.

ps- thefull stack:

Code:
javax.persistence.RollbackException: Error while commiting the transaction
   at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:71)
   at com.mit.persistencia.EntityManagerHelper.commit(EntityManagerHelper.java:46)
   at com.mit.registros.dao.RegistroDAOTest.testSave(RegistroDAOTest.java:82)
   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.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
   at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
   at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
   at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
   at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
   at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:66)
   at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
   at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
   at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
   at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
   at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
   at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
   at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)
   ... 22 more
Caused by: java.sql.SQLException: ORA-01400: cannot insert NULL into ("xxxx"."yyyy"."CD_ERROR")

   at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:114)
   at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:208)
   at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:542)
   at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1311)
   at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:738)
   at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:1313)
   at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1232)
   at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:3108)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
   ... 30 more

[/code]

_________________
Santiago García Pimentel R.G.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 06, 2009 4:06 am 
Regular
Regular

Joined: Sun Aug 01, 2004 6:49 pm
Posts: 76
What I can see from your logs Hibernate want to insert null values, but your DBMS does not allow that: Caused by: java.sql.SQLException: ORA-01400: cannot insert NULL into ("xxxx"."yyyy"."CD_ERROR")
So please allow null values.

@AttributeOverride might be something helping you.

HTH
Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 06, 2009 11:33 am 
Newbie

Joined: Fri Apr 03, 2009 4:12 pm
Posts: 9
thhart, thanks for the tip, but I really dont like that solution.

I have not a lot of experience with jpa or hibernate, but I suppose there is a way of preventing some values to be null only in some subclasses.

the problem is that all my objects from one subclass must have the cd_error value set, but that field doesnt even exist in the other subclass, so I wouldnt like to accept null values for that field.

I dont understand how @AttributeOverride might help me, could you be a little more specific?

thanks for your help.

EDIT: I tried to use @AttributeOverride to make the column nullable in my subclass. but Im getting an exception:

Code:
javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.XXX.YYY.MyClass.error
   at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:630)
   at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:219)
   at com.XXX.YYY.dao.DAO.save(DAO.java:30)
   at com.XXX.YYY.dao.DAOTest.testSave(RegistroDAOTest.java:95)
   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.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
   at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
   at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
   at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
   at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
   at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:66)
   at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
   at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
   at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
   at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.XXX.YYY.MyClass.error
   at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
   at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:290)
   at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
   at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
   at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:49)
   at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:131)
   at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:87)
   at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:38)
   at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:618)
   at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:592)
   at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:596)
   at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:213)

_________________
Santiago García Pimentel R.G.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 06, 2009 1:21 pm 
Regular
Regular

Joined: Sun Aug 01, 2004 6:49 pm
Posts: 76
As I already said, your Oracle don't like to have null values in its mapped table.

Possible Solutions:

1. Assign a default value in your oracle schema. Then you have to do the mapping for your error field only in class A. In class B will be no error field then.

2. Allow null values in your oracle schema, then the field can be null if not set and can be declared in the superclass. So you can let the mapping in the superclass.

@AttributeOverride can override a mapping of a property of a superclass. So you might be able to specify if it can be null or not.

Regarding your testing: nullable=true means a field can be null. nullable=false means it can not be null. You have intermixed your needs and your mapping examples. So you get this error now before it is sent to the database.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.