-->
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.  [ 8 posts ] 
Author Message
 Post subject: create an row of a subclass when a row in baseclass exists??
PostPosted: Tue Sep 14, 2004 10:43 am 
Newbie

Joined: Wed May 12, 2004 2:57 pm
Posts: 17
Hi,

I have a base class User and a sub class SuperUser that are mapped to tables TBL_USER and TBL_SUPER_USER using table per subclass stradegy.
My problem is that I can't find a way to "upgrade" a User object to a SuperUser object. In other words, When a User object already exists in the database, how can I create a row in the TBL_SUPER_USER table that references the existing row in the TBL_USER table?

I can't delete the existing User row and copy it into a new SuperUser object because the existing User row may already been referred in some other tables.

Thanks for any suggestions.

Hibernate version:
2.1.x

Mapping documents:
<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
<class
name="User"
table="TBL_USER"
dynamic-update="false"
dynamic-insert="false"
>

<id
name="id"
column="ID"
type="java.lang.Integer"
>
<generator class="hilo">
</generator>
</id>

<property
name="username"
type="java.lang.String"
update="true"
insert="true"
access="property"
column="USERNAME"
length="25"
not-null="true"
/>

<property
name="password"
type="java.lang.String"
update="true"
insert="true"
access="property"
column="PASSWORD"
length="25"
not-null="true"
/>

<joined-subclass
name="SuperUser"
table="TBL_SUPER_USER"
dynamic-update="false"
dynamic-insert="false"
>
<key
column="ID"
/>

<property
name="someProp"
type="java.lang.String"
update="true"
insert="true"
access="property"
column="SOME_PROP"
length="50"
/>

</joined-subclass>

</class>

</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():

Transaction trx = session.beginTransaction();
session.saveOrUpdate(obj);
trx.commit();

Full stack trace of any exception that occurs:

net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: 98729985, of class: SuperUser
at net.sf.hibernate.impl.SessionImpl.checkUniqueness(SessionImpl.java:1666)
at net.sf.hibernate.impl.SessionImpl.doUpdateMutable(SessionImpl.java:1435)
at net.sf.hibernate.impl.SessionImpl.doUpdate(SessionImpl.java:1462)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1385)
at SuperUserDAO.save(SuperUserDAO.java:160)
at UserSaveAction.execute(UserSaveAction.java:175)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at com.crosslink.web.app.filter.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:45)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:213)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2422)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:163)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:199)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:828)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:700)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:584)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:534)

Name and version of the database you are using:
Sql Server 2k

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 14, 2004 11:01 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
you cannot change a type in java --> so it is impossible

the way to do it:
1- get baseObject
2- create new subObject
3- copy all from baseObject to subObject
4- delete baseObject
5- save subObject

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 14, 2004 11:14 am 
Newbie

Joined: Wed May 12, 2004 2:57 pm
Posts: 17
Anthony,

I can't simply delete the base object as it is referenced by many other objects.
So I guess I need to save the subObject first? Then is there a easy way to update all other objects that are referencing the old baseObject to reference the new subObject before I delete the old baseObject?

Thank you!


Top
 Profile  
 
 Post subject: Re: create an row of a subclass when a row in baseclass exis
PostPosted: Sun Sep 19, 2004 10:13 am 
Newbie

Joined: Fri Jul 30, 2004 4:17 am
Posts: 5
Location: Sydney, Australia
gah. I've run into exactly the same problem. I'm going to have a think about how I designed my app and let you know of any ways that appeal to me.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 19, 2004 10:48 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
that's a good point, tell the community how you manage it

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 20, 2004 9:41 am 
Newbie

Joined: Wed May 12, 2004 2:57 pm
Posts: 17
Well, I just worked around it by using composition instead of inheritance


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 20, 2004 10:25 pm 
Newbie

Joined: Fri Jul 30, 2004 4:17 am
Posts: 5
Location: Sydney, Australia
yep me too.
I doing something similar to the one-to-one mapping example in the online docs.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 22, 2004 12:28 pm 
Newbie

Joined: Wed Sep 22, 2004 12:18 pm
Posts: 14
I had the same problem...and deletion and re-insert is not a viable option, for many reasons, cascade-delete being the primary.

the solution I opted for is a simple jdbc insert into the joined-subclass table with that foreign-key ( all other columns can be left empty), and then doing the regular update via Hibernate. The existence of that row in the sub-class table will make Hibernate happy.

btw, Hibernate should really be able to handle this automatically, leveraging the Oracle upsert statement... [/quote]


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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.