-->
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.  [ 10 posts ] 
Author Message
 Post subject: Is composite key value setting manual?
PostPosted: Fri Dec 10, 2004 7:10 am 
Newbie

Joined: Thu Dec 09, 2004 12:29 pm
Posts: 10
Hello,

I am currently manually updating the foreign key values in my composite ids. Is this a correct way of doing it or can I map them in a way that will update them automatically?

Here is an example. A correspondent (which has a natively generated id) had multiple telephones which are keyed by correspondent id and the telephone type. I have no problems setting the type of the telephone, however I need to set the correspondent foreign key within telephone composite key after correspondent is saved to the database and an id is assigned to that correspondent. I really don't want to do it manually, so I wondering whether there is a way of mapping it correctly in order for correspondent id foreign key in telephone to be updated automatically.


Hibernate version: 2



Mapping documents:

Telephones mapping:

<hibernate-mapping>

<class name="Telephone" table="TELEPHONES">

<composite-id name="comp_id" class="TelephonePK">
<key-property name="custid" column="CUSTID" type="java.math.BigDecimal" length="9" />
<key-property name="type" column="TELTYPE" type="CustomStringTrimType" length="30" />
</composite-id>

<timestamp name="timeStamp" column="DATETIME" unsaved-value="null" />

<property name="userStamp" type="java.lang.String" column="USERSTAMP" length="10" />
<property name="number" type="CustomStringTrimType" column="TELNUM" length="20" />
<property name="std" type="CustomStringTrimType" column="TELCODE" length="10" />

<property name="extension" type="CustomStringTrimType" column="EXTENSION" length="10" />

</class>
</hibernate-mapping>


Correspondent mapping of telephones:

<set name="telephones" lazy="false" inverse="true" cascade="all">
<key>
<column name="CUSTID" />
</key>
<one-to-many class="Telephone" />
</set>






Thanks for your help,
Elena


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 10, 2004 8:01 am 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
You can use <key-mant-to-one ...

regards
Peco


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 10, 2004 9:23 am 
Newbie

Joined: Thu Dec 09, 2004 12:29 pm
Posts: 10
Hi Peco,

I have tried this, however it still tries to insert a NULL into the foreign key of the composite key:

org.springframework.dao.DataIntegrityViolationException: (HibernateAccessor): data integrity violated by SQL 'null'; nested exception is java.sql.SQLException: [SQL0407] Null values not allowed in column or variable CUSTID.
java.sql.SQLException: [SQL0407] Null values not allowed in column or variable CUSTID.
at com.ibm.as400.access.JDError.throwSQLException(JDError.java:594)
at com.ibm.as400.access.JDError.throwSQLException(JDError.java:565)
at com.ibm.as400.access.AS400JDBCStatement.commonExecute(AS400JDBCStatement.java:845)
at com.ibm.as400.access.AS400JDBCPreparedStatement.executeUpdate(AS400JDBCPreparedStatement.java:1109)
at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:464)
at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:438)
at net.sf.hibernate.impl.ScheduledInsertion.execute(ScheduledInsertion.java:37)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2438)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2391)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2260)
at org.springframework.orm.hibernate.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:202)
at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:151)
at org.springframework.orm.hibernate.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:257)
at net.targetgroup.broker.correspondent.TelephoneDAOHibernate.saveTelephone(TelephoneDAOHibernate.java:45)
at net.targetgroup.broker.hibernate.TelephoneDAOTest.testSaveTelephone(TelephoneDAOTest.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:41)
at java.lang.reflect.Method.invoke(Method.java:386)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:392)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:276)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:167)


Am I doing something wrong? Here are my amended mapping files and the code for the telephones composite key class:


mapping file for telephone:

<hibernate-mapping>

<class name="Telephone" table="TELEPHONES">

<composite-id name="comp_id" class="TelephonePK">
<!-- <key-property name="custid" column="CUSTID" type="java.math.BigDecimal" length="9" /> -->
<key-many-to-one name="correspondent" class="Correspondent">
<column name="CUSTID" />
</key-many-to-one>
<key-property name="type" column="TELTYPE" type="CustomStringTrimType" length="30" />
</composite-id>

<timestamp name="timeStamp" column="DATETIME" unsaved-value="null" />

<property name="userStamp" type="java.lang.String" column="USERSTAMP" length="10" />
<property name="number" type="CustomStringTrimType" column="TELNUM" length="20" />
<property name="std" type="CustomStringTrimType" column="TELCODE" length="10" />

<property name="extension" type="CustomStringTrimType" column="EXTENSION" length="10" />

</class>
</hibernate-mapping>


Mapping of telephone in the correspondent:

<!-- bi-directional one-to-many association to Telephone -->
<set name="telephones" lazy="false" inverse="true" cascade="all">
<key>
<column name="CUSTID" />
</key>
<one-to-many class="net.targetgroup.broker.correspondent.Telephone" />
</set>


composite key class:

public class TelephonePK implements Serializable {
private static final Logger LOG = Logger.getLogger(TelephonePK.class);
/** identifier field */
private Correspondent correspondent;

/** identifier field */
private String type;

/** full constructor */
public TelephonePK(Correspondent newCorrespondent, String newType) {
this.correspondent = newCorrespondent;
this.type = newType;
}

/** default constructor */
public TelephonePK() {
}

/**
* @see java.lang.Object#toString()
*/
public String toString() {

return new ToStringBuilder(this)
.append("cuorrespondent", getCorrespondent())
.append("type", getType())
.toString();
}

/**
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object other) {
if (!(other instanceof TelephonePK))
return false;
TelephonePK castOther = (TelephonePK) other;
EqualsBuilder builder = new EqualsBuilder();
if (getCorrespondent() != null
&& castOther.getCorrespondent() != null) {
builder.append(
this.getCorrespondent().toString(),
castOther.getCorrespondent().toString());
} else {
if (getCorrespondent() != castOther.getCorrespondent()) {
//if one is null but not the other
return false;
}
}

builder.append(this.getType(), castOther.getType());

return builder.isEquals();
}

/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {

HashCodeBuilder builder = new HashCodeBuilder();
if (getCorrespondent() != null) {
builder.append(getCorrespondent().toString());
}

builder.append(getType()).toHashCode();
return builder.toHashCode();
}

/**
* @return
*/
public String getType() {
return type;
}

/**
* @param string
*/
public void setType(String string) {
type = string;
}

/**
* @return
*/
public Correspondent getCorrespondent() {
return correspondent;
}

/**
* @param correspondent
*/
public void setCorrespondent(Correspondent correspondent) {
this.correspondent = correspondent;
}


Cheers for your help,
Elena


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 10, 2004 11:02 am 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
I think that You have to make new instance for foreign key and add it in master
What is your code for update (between openSession and commit)

regards


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 10, 2004 11:40 am 
Newbie

Joined: Thu Dec 09, 2004 12:29 pm
Posts: 10
I actually got it to work earlier on, but I had to manually set the 'Foreign class' on the composite key. :-(
I was originally hoping hibernate would work it out as one class contains the other...

here is the code sample:

Applicant customer = new Applicant();

customer.setAlias("Dr Thong");
customer.setBank(BankDAOTest.createBank());
customer.setBankrupt(true);
customer.setApplicationIdentifier(1);

Telephone telephone = new Telephone();
telephone.setType(Telephone.FAX);
telephone.setNumber("07989999999");
telephone.getComp_id().setCorrespondent(customer);
//the above line resides in addTelephone method below, but I have taken it out for this sample code
customer.addTelephone(telephone);
dao.saveCustomer(customer);


Am I correct? Or is there a way to automate it through hibernate....

Thanks in advance,
Elena


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 10, 2004 12:39 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
Elena,
I don't understand what is for you foreign key
Foreign key have to exists in foreign table when you save master
It is role of foreign key - deny save master if foreign not exists
If you create foreign and master together you have to save foreign first and then master
databse constraint (foreign key) denied different (except when foreign key can be null -
then database accept null in foreign key)

regards


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 10, 2004 1:36 pm 
Newbie

Joined: Thu Dec 09, 2004 12:29 pm
Posts: 10
Appologies if I was unclear. Basically, I had to set the master instance on the composite key manually. If you have a look at my earlier posted code and mappings, there is a master called Correspondent which has a foreign key inside a composite key of its child Telephone. In order for the foreign key within the composite key of Telephone to be updated when I save or update Correspondent (which contains this telephone in a collection) I had to manually set the Correspondent object on the composite key class of telephone.

Here are the mapping files again:

<hibernate-mapping>

<class name="Telephone" table="TELEPHONES">

<composite-id name="comp_id" class="TelephonePK">
<!-- <key-property name="custid" column="CUSTID" type="java.math.BigDecimal" length="9" /> -->
<key-many-to-one name="correspondent" class="Correspondent">
<column name="CUSTID" />
</key-many-to-one>
<key-property name="type" column="TELTYPE" type="CustomStringTrimType" length="30" />
</composite-id>

<timestamp name="timeStamp" column="DATETIME" unsaved-value="null" />

<property name="userStamp" type="java.lang.String" column="USERSTAMP" length="10" />
<property name="number" type="CustomStringTrimType" column="TELNUM" length="20" />
<property name="std" type="CustomStringTrimType" column="TELCODE" length="10" />

<property name="extension" type="CustomStringTrimType" column="EXTENSION" length="10" />

</class>
</hibernate-mapping>


Mapping of telephone in the correspondent:

<!-- bi-directional one-to-many association to Telephone -->
<set name="telephones" lazy="false" inverse="true" cascade="all">
<key>
<column name="CUSTID" />
</key>
<one-to-many class="net.targetgroup.broker.correspondent.Telephone" />
</set>


composite key class :

public class TelephonePK implements Serializable {
private static final Logger LOG = Logger.getLogger(TelephonePK.class);
/
** This is the master I have to set manually before I save */


private Correspondent correspondent;


/** identifier field */
private String type;

/** full constructor */
public TelephonePK(Correspondent newCorrespondent, String newType) {
this.correspondent = newCorrespondent;
this.type = newType;
}

/** default constructor */
public TelephonePK() {
}

...



The code that saves the lot is calling a save on Correspondent (the master), which contains a set of Telephones (the child) that has the composite key I have mentioned earlier. If I do not set the Correspondent (master) on Telephone using getComp_id().setCorrespondent(...) , it will try to incert a NULL into the correspondent foreign key on the telephone table in the database. I am currently setting Correspondent instance manually via getComp_id().setCorrespondent(...) on each Telephone object that Correspondent contains.

Hope this clarifies my situation

Any help is really appreciated,
Elena


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 10, 2004 1:40 pm 
Newbie

Joined: Thu Dec 09, 2004 12:29 pm
Posts: 10
Sorry, I misunderstood what you meant by the master (It must be friday madness ;). Correspondent is the foreign table and Telephone is the master. Correspondent object contains many Telephone objects. Telephone table has a foreign key to Correspondent table as part of its composite primary key......

Have a good w/e


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 10, 2004 5:12 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
I confused totaly - rule is simple (relational database reference rule, not hibernate) : foreign key
must exits before saving master

regards


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 14, 2004 5:25 am 
Newbie

Joined: Thu Dec 09, 2004 12:29 pm
Posts: 10
Sure, I know about this rule, that was not the problem. Anyway, it works with bit of manual coding required when persisting objects with composite keys in hibernate, which I was hoping to avoid...


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