-->
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.  [ 9 posts ] 
Author Message
 Post subject: Integer primary key configuration problems
PostPosted: Fri Feb 06, 2009 9:12 pm 
Newbie

Joined: Fri Feb 06, 2009 8:57 pm
Posts: 8
Hi there,

I am running into a problem when trying to configure a hibernate mapping of a POJO integer key to mysql integer key.

If I try to configure it using type java.lang.String I don't seem to have any problems. The key is auto-generated (looks like a GUID to me), but it's a String and I want it to be an INT.

Whenever I use a type other than String it throws an exception saying it's unable to typecast TYPE to java.lang.String.

I made a few changes to getId() to fix the exception, but I don't think I'm getting anywhere with that. Even then, if I try to update nothing happens; no inserts.

I am stuck here and no books or tutorials are steering me to the right direction.

Below are the details:

Hibernate version: hibernate-2.1.3.jar
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>
<!-- Java file name and table name -->
<class name="mytest.dao.Customer" table="customer"
dynamic-update="false" dynamic-insert="false">

<!-- A 32 bit hex key for the internal Hibernate DB key -->
<id name="id" column="id" type="int">
<generator class="native" />
</id>

<!-- Now the custNum and its attributes-->
<property name="custNum" type="int" update="true" insert="true" column="custNum" not-null="true" unique="true" />
<property name="name" type="java.lang.String" update="true" insert="true" column="name" />

<!-- We may convert this later into a link to another table -->
<property name="address" type="java.lang.String" update="true" insert="true" column="address" not-null="true" length="255" />
</class>
<!--
Now we have defined the mapping between the Java object "Customer" and
the table "customer"
-->


<!-- Here we can define some custom queries to run -->
<query name="mytest.dao.customer.get"><![CDATA[
select customer from mytest.dao.Customer as customer where customer.custNum = :custNum
]]></query>
<query name="mytest.dao.customer.findAll"><![CDATA[
select customer from mytest.dao.Customer as customer order by customer.custNum
]]></query>
<query name="mytest.dao.customer.exist"><![CDATA[
select count(customer) from mytest.dao.Customer as customer where customer.custNum = :custNum
]]></query>
</hibernate-mapping>

Code between sessionFactory.openSession() and session.close():
Using a few extended classes to simplify the code. It is as follows:

this.hibernate().init();
this.hibernate().begin();
Customer c = new Customer();
//c.setCustNum(123);
c.setAddress("1111 Nelson");
c.setName("Tim H");
this.hibernate().saveOrUpdate(c);
this.hibernate().commit();
this.hibernate().close();


Full stack trace of any exception that occurs:
exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:583)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

root cause

java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String
net.sf.hibernate.type.StringType.set(StringType.java:26)
net.sf.hibernate.type.NullableType.nullSafeSet(NullableType.java:48)
net.sf.hibernate.type.NullableType.nullSafeSet(NullableType.java:35)
net.sf.hibernate.persister.EntityPersister.dehydrate(EntityPersister.java:399)
net.sf.hibernate.persister.EntityPersister.update(EntityPersister.java:666)
net.sf.hibernate.persister.EntityPersister.update(EntityPersister.java:640)
net.sf.hibernate.impl.ScheduledUpdate.execute(ScheduledUpdate.java:52)
net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2407)
net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2361)
net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2229)
net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
com.fcv.spring.FCVHibernate.commit(FCVHibernate.java:67)
chawk2.web.AdminController.handleRequest(AdminController.java:83)
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)



Name and version of the database you are using:
mysql-connector-java-3.1.14-bin.jar
MySQL 5

Customer.java
package mytest.dao;

public class Customer {

private int id; //Internal Hibernate DB id
private int custNum; //Unique id
private String name;
private String address;

public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getCustNum() {
return custNum;
}
public void setCustNum(int custNum) {
this.custNum = custNum;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}

}


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 07, 2009 2:53 pm 
Expert
Expert

Joined: Fri Jan 30, 2009 1:47 am
Posts: 292
Location: Bangalore, India
Quote:
<id name="id" column="id" type="int">

Instead of int try with java.lang.Integer


Quote:
Customer c = new Customer();
//c.setCustNum(123);
c.setAddress("1111 Nelson");
c.setName("Tim H");
this.hibernate().saveOrUpdate(c);

Here custNum is a non-null field, but you hav commented out the call to set it. ???

_________________
Regards,
Litty Preeth


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 08, 2009 8:47 pm 
Newbie

Joined: Fri Feb 06, 2009 8:57 pm
Posts: 8
Thanks very much for reply.

I tried java.lang.Integer as well with no luck.
I still get typecasting exceptions...

custNum commented out code may look a bit strange, I agree. In my MySQL table `custNum` is the primary key (INT and AUTO increment), while `id` is just a dummy field used to make Hibernate work. The drawback, of course, is that I can't configure Hibernate to recognize custNum as primary key via <id> tags using an Integer type.

As a workaround, I am using `id` as hibernate id and custNum as my primary key. This makes no sense though, and I'd be really happy if I could replace `id` with `custNum`. I'm not sure why I'm running into this issue. I can't seem to find anything similar happening to others.

This is my table definition so far:


Code:
CREATE TABLE  `customer` (
  `name` varchar(45) default NULL,
  `address` varchar(255) default NULL,
  `id` varchar(32) NOT NULL,
  `custNum` int(10) unsigned NOT NULL auto_increment,
  PRIMARY KEY  USING BTREE (`custNum`),
  KEY `index_id` (`id`)
);


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 09, 2009 12:50 am 
Expert
Expert

Joined: Fri Jan 30, 2009 1:47 am
Posts: 292
Location: Bangalore, India
Quote:
`id` varchar(32) NOT NULL

In the table id is varchar type, but in the mapping you are specifying it as int.

_________________
Regards,
Litty Preeth


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 09, 2009 2:57 am 
Newbie

Joined: Fri Feb 06, 2009 8:57 pm
Posts: 8
Oops. thanks for pointing that out; I should have clarified. That's how it currently working: id=hibernate generated string key, custNum=mysql generated int key.

The way it should ideally be is:

Code:
CREATE TABLE  `customer` (
  `name` varchar(45) default NULL,
  `address` varchar(255) default NULL,
  `id` int(10) unsigned NOT NULL auto_increment,
  PRIMARY KEY  USING BTREE (`id`)
)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 09, 2009 4:42 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Could the problem be that you have declared the 'id' column as 'unsigned'? In Java there are no unsigned data types and a regular (java) int can't hold the same range of values as an unsigned int in MySQL. Since the stacktrace in the first post shows that you are getting a 'long' value it may be that the JDBC driver automatically converts a (mysql) unsigned int to (java) long. Note that this is just a theory, I have not tested this. If the theory is true, there are two ways forward.

1. Use 'long' id values in your Java classes and Hibernate mappings.
2. Don't use 'unsigned' int in MySQL.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 09, 2009 5:23 pm 
Newbie

Joined: Fri Feb 06, 2009 8:57 pm
Posts: 8
Thanks for the feedback. I appreciate the help.
It appears that the exception no longer occurs with Long which is great.

I have also removed the unsigned from all fields in my MySQL table.

However, now nothing happens again when I try to insert a record, but using a string id works. I tried using long and java.lang.Long in my hibernate mappings (<id> tag).

Any ideas?

Could the insert SQL generated by hibernate be incorrect?

Thanks,
Tim


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 09, 2009 6:02 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
It's kind of hard to help you without some more information. For example, the mappings you are using now and the code that is supposed to do something, debug logs, etc.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 09, 2009 11:40 pm 
Newbie

Joined: Fri Feb 06, 2009 8:57 pm
Posts: 8
nordborg wrote:
It's kind of hard to help you without some more information. For example, the mappings you are using now and the code that is supposed to do something, debug logs, etc.


This totally makes sense. I skipped the important step of setting up log4j.
Once I saw debug logs the problem was simple. I was trying to update but a record but there was no id set for customer object.


Cheers,

Tim


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