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: multiple reference to the same object
PostPosted: Fri Nov 14, 2008 9:05 pm 
Newbie

Joined: Fri Aug 15, 2008 7:04 pm
Posts: 5
Hi,

Here is the simplified problem -- I have Object A which contains Object B and C. Both B and C refers to the same Object D. When I call save on A with cascade="all", save fails on saving D the second time. I thought hibernate should know that D is already persisted and thus will not do it the second time. But it always does it and I could not find a way to make hibernate not to do it. This is such a fundamental problem I am sure that hibernate already has a solution. Can anybody let me know?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 15, 2008 12:22 am 
Expert
Expert

Joined: Mon Nov 26, 2007 2:29 pm
Posts: 443
It might relate to whether D is declared as an entity or as a "value type", with no independent lifecycle.
Please provide some client code example, and the mapping file.

_________________
Gonzalo Díaz


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 17, 2008 1:21 pm 
Newbie

Joined: Fri Aug 15, 2008 7:04 pm
Posts: 5
I deflared as a entity type. Below is the mapping file. I call save on the top-level ApplicationProfile or SecurityModuleProfile object and depend on cascade to save the sub-objects (composition and aggregation). So you know the situation should be handled automatically by Hibernate, right? Then is there any property I did not set...etc.?

Some of the object, like ApplicationActionTemplate instances, are shared by both ApplicationState and by SecurityModuleComponentActionTemplate objects. The ApplicationState (first parent) object is saved first and the related ApplicationActionTemplate objects are saved. Then when SecurityModuleComponentActionTemplate (second parent) are saved, Hibernate throws a NonUniqueObjectException complaining about the children (ApplicationActionTemplate) are already exists in session.

Thanks alot for your help

Michael

---- java file ----

public Object create(Object o) {
Session session = getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
Object temp = session.save(o);
tx.commit();
return temp;
}

---- mapping file ------

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.actividentity.iasp.manager.profile" >
<typedef class="com.actividentity.iasp.manager.profile.dao.StringEnumUserType" name="TASK_TYPE_ENUM" >
<param name="enumClassName">com.actividentity.iasp.manager.profile.ScriptTemplate$TaskType</param>
</typedef>

<!-- ######################################################################### -->
<!-- class hierarchies based on Profile -->
<!-- ######################################################################### -->

<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
<!-- abstract class ProfileDelegate -->
<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
<class name="com.actividentity.iasp.manager.profile.dao.ProfileDelegate" abstract="true">
<!-- id and type are from ProfileId (ConfigurationId) contained in Managed -->
<id name="id" column="id" length="150" type="string">
<generator class="assigned" />
</id>
<property name="type" type="string">
<column name="type" length="50" not-null="true" />
</property>
<!-- *********************************** -->
<!-- class AliasProfile extends Profile -->
<!-- *********************************** -->
<union-subclass name="com.actividentity.iasp.manager.profile.dao.AliasProfileDelegate"
table="alias_profile">
<property name="alias" type="string">
<column name="alias" length="50" not-null="true" />
</property>
</union-subclass>
<!-- ******************************************* -->
<!-- class ApplicationProfile extends Profile -->
<!-- (#1) -->
<!-- ******************************************* -->
<union-subclass name="com.actividentity.iasp.manager.profile.dao.ApplicationProfileDelegate"
table="application_profile">
<component name="workflowId" class="WorkflowId">
<property name="id" column ="workflow_id" type="string" />
<property name="type" column ="workflow_type" type="string" />
<property name="version" column ="workflow_version" type="integer" />
</component>
<property name="workflowStartState" type="string">
<column name="workflow_start_state" length="50" not-null="true" />
</property>
<bag name="profileArtifacts" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="ProfileArtifact" />
</bag>
<bag name="workflowStates" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="ApplicationState" />
</bag>
</union-subclass>
<!-- ******************************************** -->
<!-- class SecurityModuleProfile extends Profile -->
<!-- (#2) -->
<!-- ******************************************** -->
<union-subclass name="com.actividentity.iasp.manager.profile.dao.SecurityModuleProfileDelegate"
table="sec_module_profile">
<component name="workflowId" class="WorkflowId">
<property name="id" column ="workflow_id" type="string" />
<property name="type" column ="workflow_type" type="string" />
<property name="version" column ="workflow_version" type="integer" />
</component>
<property name="workflowStartState" type="string">
<column name="workflow_start_state" length="50" not-null="true" />
</property>
<bag name="securityModuleComponentTemplates" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="SecurityModuleComponentTemplate" />
</bag>
<bag name="workflowStates" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="SecurityModuleState" />
</bag>
<bag name="applicationProfileIds" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="ProfileId" />
</bag>
</union-subclass>
</class>

<!-- ################################################################## -->
<!-- class hierarchies based on ProfileFragment -->
<!-- ################################################################## -->

<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
<!-- abstract class ProfileFragment -->
<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
<class name="ProfileFragment" abstract="true">
<id column="rid" type="long">
<generator class="native" />
</id>
<!--
<id name="id" column="id" length="150" type="string">
<generator class="assigned" />
</id>
-->
<property name="id" type="string" column="id" />
<property name="parentId" type="string" column="parent_id" />
<!-- ********************************************* -->
<!-- class ProfileArtifact extends ProfileFragment -->
<!-- ********************************************* -->
<union-subclass name="ProfileArtifact" table="profile_artifact">
<property name="label" type="string">
<column name="label" length="150" />
</property>
<property name="type" type="string">
<column name="type" length="150" />
</property>
<property name="artifact" type="com.actividentity.iasp.manager.profile.dao.StringClobType">
<column name="artifact" />
</property>
</union-subclass>
<!-- ********************************************** -->
<!-- class ApplicationState extends ProfileFragment -->
<!-- ********************************************** -->
<union-subclass name="ApplicationState" table="application_state">
<property name="workflowState" type="string" column="workflow_state" />
<bag name="attributes" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="com.actividentity.iasp.util.beans.Parameter" />
</bag>

<bag name="applicationActionTemplates" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="ApplicationActionTemplate" />
</bag>
<!--
<bag name="applicationActionTemplates" cascade="all" lazy="false" table="aat_link_table" >
<key column="ancestor_id" />
<many-to-many class="ApplicationActionTemplate" column="aat_id" unique="false" />
</bag>
-->
<bag name="artifactAliases" cascade="all" table="artifact_alias" lazy="false">
<key column="ancestor_id" />
<composite-element class="ArtifactAlias">
<property name="id" column="id" type="string" />
<property name="type" column="type" type="string" />
</composite-element>
</bag>
</union-subclass>
<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
<!-- abstract class ScriptTemplate extends ProfileFragment -->
<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
<union-subclass name="ScriptTemplate" abstract="true">
<property name="applicationLabel" type="string" column="application_label" />
<property name="taskType" type="TASK_TYPE_ENUM" column="task_type"
not-null="true" update="false" access="field" />
<property name="scriptName" type="string" column="script_name" />

<!-- ******************************************************* -->
<!-- class ApplicationScriptTemplate extends ScriptTemplate -->
<!-- ******************************************************* -->
<union-subclass name="ApplicationScriptTemplate" table="script_template">
</union-subclass>
<!-- ******************************************************* -->
<!-- class SecurityModuleScriptTemplate extends ScriptTemplate -->
<!-- ******************************************************* -->
<union-subclass name="CredentialScriptTemplate" table="credential_script_template">
<property name="credentialLabel" type="string" column="credential_label" />
<property name="credentialType" type="string" column="credential_type" />
</union-subclass>
</union-subclass>
<!-- ******************************************************************* -->
<!-- #2.3 class SecurityModuleComponentTemplate extends ProfileFragment -->
<!-- ******************************************************************* -->
<union-subclass name="SecurityModuleComponentTemplate" table="sec_module_comp_template">
<component name="workflowId" class="WorkflowId">
<property name="id" column ="workflow_id" type="string" />
<property name="type" column ="workflow_type" type="string" />
<property name="version" column ="workflow_version" type="integer" />
</component>
<property name="type" type="string" column="type" />
<property name="workflowStartState" type="string" column="workflow_start_state" />
<bag name="attributes" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="com.actividentity.iasp.util.beans.Parameter" />
</bag>
<bag name="profileArtifacts" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="ProfileArtifact" />
</bag>
<bag name="workflowStates" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="SecurityModuleComponentState" />
</bag>
</union-subclass>
<!-- ****************************************************** -->
<!-- #2.4 class SecurityModuleState extends ProfileFragment -->
<!-- ****************************************************** -->
<union-subclass name="SecurityModuleState" table="sec_module_state">
<property name="workflowState" type="string" column="workflow_state" />
<bag name="attributes" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="com.actividentity.iasp.util.beans.Parameter" />
</bag>
<bag name="securityModuleActionTemplates" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="SecurityModuleActionTemplate" />
</bag>
<bag name="artifactAliases" cascade="all" table="artifact_alias" lazy="false">
<key column="ancestor_id" />
<composite-element class="ArtifactAlias">
<property name="id" column="id" type="string" />
<property name="type" column="type" type="string" />
</composite-element>
</bag>
</union-subclass>
<!-- ********************************************************** -->
<!-- class SecurityModuleComponentState extends ProfileFragment -->
<!-- (2.3.4) -->
<!-- ********************************************************** -->
<union-subclass name="SecurityModuleComponentState" table="sec_module_comp_state">
<property name="workflowState" type="string" column="workflow_state" />
<bag name="attributes" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="com.actividentity.iasp.util.beans.Parameter" />
</bag>
<bag name="applicationTemplates" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="ApplicationTemplate" />
</bag>
<bag name="artifactAliases" cascade="all" table="artifact_alias" lazy="false">
<key column="ancestor_id" />
<composite-element class="ArtifactAlias">
<property name="id" column="id" type="string" />
<property name="type" column="type" type="string" />
</composite-element>
</bag>
<bag name="securityModuleComponentActionTemplates" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="SecurityModuleComponentActionTemplate" />
</bag>
</union-subclass>
<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
<!-- abstract class ActionTemplate extends ProfileFragment -->
<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
<union-subclass name="ActionTemplate" abstract="true">
<property name="workflowState" type="string" column="workflow_state" />
<property name="workflowTransition" type="string" column="workflow_transition" />
<!-- ********************************************************* -->
<!-- class SecurityModuleActionTemplate extends ActionTemplate -->
<!-- (2.4.3 -->
<!-- ********************************************************* -->
<union-subclass name="SecurityModuleActionTemplate" table="sec_module_action_template">
<bag name="inputRequirements" cascade="all" table="profile_entry" lazy="false">
<key column="ancestor_id" />
<composite-element class="com.actividentity.iasp.manager.configuration.Entry">
<property name="key" type="string" not-null="true">
<column name="KEY" length="150" />
</property>
<property name="label" type="string">
<column name="LABEL" length="150" />
</property>
<property name="dynamic" type="boolean">
<column name="IS_DYNAMIC" precision="1" scale="0" not-null="true" />
</property>
<property name="sensitive" type="boolean">
<column name="IS_SENSITIVE" precision="1" scale="0" not-null="true" />
</property>
<property name="value" type="string">
<column name="VALUE" length="4000" not-null="true" />
</property>
</composite-element>
</bag>
<bag name="securityModuleComponentActionTemplates" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="SecurityModuleComponentActionTemplate" />
</bag>
</union-subclass>
<!-- ****************************************************************** -->
<!-- class SecurityModuleComponentActionTemplate extends ActionTemplate -->
<!-- (2.3.4.4), (2.4.3.2) -->
<!-- ****************************************************************** -->
<union-subclass name="SecurityModuleComponentActionTemplate" table="sec_module_comp_act_template">
<property name="securityModuleComponentType" type="string" column="sec_module_component_type" />
<!--
<bag name="applicationActionTemplates" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="ApplicationActionTemplate" />
</bag>
-->
<!--
<bag name="applicationActionTemplates" cascade="all" lazy="false" table="aat_link_table" >
<key column="ancestor_id" />
<many-to-many class="ApplicationActionTemplate" column="aat_id" unique="false" />
</bag>
-->
</union-subclass>
<!-- ******************************************************* -->
<!-- class ApplicationActionTemplate extends ActionTemplate -->
<!-- (2.3.3.4.1) -->
<!-- ******************************************************* -->
<union-subclass name="ApplicationActionTemplate" table="application_action_template">
<property name="applicationLabel" type="string" column="application_label" />
<property name="critical" type="boolean" column="is_critical" />
<component name="applicationProfileId" class="ProfileId">
<property name="id" type="string" column="profile_id" />
<property name="type" type="string" column="profile_type" />
</component>
<!--
<bag name="scriptTemplates" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="ApplicationScriptTemplate" />
</bag>
-->
<!-- temporary until solve polymorphism association issues -->
<bag name="applicationScriptTemplates" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="ApplicationScriptTemplate" />
</bag>
<bag name="credentialScriptTemplates" cascade="all" lazy="false">
<key column="ancestor_id" />
<one-to-many class="CredentialScriptTemplate" />
</bag>

<bag name="inputRequirements" cascade="all" table="profile_entry" lazy="false">
<key column="ancestor_id" />
<composite-element class="com.actividentity.iasp.manager.configuration.Entry">
<property name="key" type="string" not-null="true">
<column name="KEY" length="150" />
</property>
<property name="label" type="string">
<column name="LABEL" length="150" />
</property>
<property name="dynamic" type="boolean">
<column name="IS_DYNAMIC" precision="1" scale="0" not-null="true" />
</property>
<property name="sensitive" type="boolean">
<column name="IS_SENSITIVE" precision="1" scale="0" not-null="true" />
</property>
<property name="value" type="string">
<column name="VALUE" length="4000" not-null="true" />
</property>
</composite-element>
</bag>
</union-subclass>
</union-subclass>
<!-- ********************************************************** -->
<!-- class ApplicationTemplate extends ProfileFragment -->
<!-- (#2.3.4.2) -->
<!-- ********************************************************** -->
<union-subclass name="ApplicationTemplate" table="application_template">
<property name="applicationLabel" type="string" column="application_label" />
<property name="workflowState" type="string" column="workflow_state" />
<property name="description" type="string" column="description" />
<property name="manageable" type="boolean" column="is_manageable" />
<component name="applicationProfileId" class="ProfileId">
<property name="id" type="string" column="profile_id" />
<property name="type" type="string" column="profile_type" />
</component>
</union-subclass>
</class>



<!-- ################################################################ -->
<!-- other classes -->
<!-- ################################################################ -->
<class name="com.actividentity.iasp.util.beans.Parameter" table="parameter">
<id name="id" column="id" length="150" type="string">
<generator class="assigned" />
</id>
<property name="value" type="string" column="value" />
</class>

<class name="ProfileId" table="profile_id">
<id name="id" column="id" length="150" type="string">
<generator class="assigned" />
</id>
<property name="type" type="string" column="type" />
</class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 17, 2008 3:17 pm 
Expert
Expert

Joined: Mon Nov 26, 2007 2:29 pm
Posts: 443
The mapping you show will not cause the error.
Shared parents won't try to save a children twice, because Hibernate is smart enough to know that, in one-to-many relations, what is recorded is the relationship between the objects, not the objects themselves.

Your problem must be in the client code. I see 2 possible causes:

Either the generic code that you use to save the objects fails to really grab the "current session", and instead creates a new session that knows nothing about a previous child object already existing. This would be unlikely if that code is already working well in other parts of your application for one-to-many relationships.

-or-

the client code that calls your generic method is, mistakenly, trying to create again a child with the same id. This would be true if anywhere in your code you are assigning an id to ApplicationActionTemplate

_________________
Gonzalo Díaz


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 17, 2008 6:02 pm 
Newbie

Joined: Fri Aug 15, 2008 7:04 pm
Posts: 5
Thanks a lot for your time and help!

I already checked the second possibility a couple of days ago. I found that the object belongs to the second parent are different objects in memory but has the same id. So to check out whether this is the problem I used a map and put id->object into the map. Then for the second parent, I loop though all objects and if I can find the id in map, I replace it using the value object in the map. This way it ensures that the two objects are the same object in memory. But the code still fails. Does this leave only the first possibility?

Also, I forgot to elaborate -- the higher level save() API takes either he first parent (an ApplicationProfile) or the secon parent (a SecurityModuleProfile). When called for an ApplicationProfile, everything is OK. then the same method is called for SecurityModuleProfile (second parent) then the NonUniqueObjectException is thrown. I am assuming that it is using the same session and thus reattaching is not needed.

Michael


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 17, 2008 6:23 pm 
Newbie

Joined: Thu Nov 13, 2008 3:25 pm
Posts: 5
If your objects are different but carry the same id did you implement proper
equals() and hashCode() on the class?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 17, 2008 7:28 pm 
Newbie

Joined: Fri Aug 15, 2008 7:04 pm
Posts: 5
I did not write the code and did not investigate. I did not understand why the objects are duplicated in the first place.

Anyway, Since I get rid of the duplicate objects already (using a map and ensure that only one object is used for each id). this is not a problem at all.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 17, 2008 7:36 pm 
Expert
Expert

Joined: Mon Nov 26, 2007 2:29 pm
Posts: 443
Quote:
I loop though all objects and if I can find the id in map, I replace it using the value object in the map. This way it ensures that the two objects are the same object in memory. But the code still fails. Does this leave only the first possibility?


OK, how do you "replace"?

And, does it occur in the same session that queried those objects, or in a different one?

_________________
Gonzalo Díaz


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.