-->
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.  [ 12 posts ] 
Author Message
 Post subject: how to update or remove a many-to-many relationship?
PostPosted: Sun May 15, 2005 12:04 pm 
Regular
Regular

Joined: Mon Aug 02, 2004 9:33 am
Posts: 69
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version:3.0

Mapping documents:
<hibernate-mapping
>
<class
name="com.stufftolet.model.businessobject.Users.User"
table="Users"
>
<cache usage="read-write" />

<id
name="id"
column="USERID"
type="java.lang.String"
length="20"
unsaved-value="null"
>
<generator class="assigned">
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-User.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>

<set
name="roles"
table="user_role"
lazy="false"
cascade="save-update"
sort="unsorted"
>

<key
column="id"
>
</key>

<many-to-many
class="com.stufftolet.model.businessobject.Role"
column="rolename"
outer-join="auto"
/>

</set>
</hibernate-mapping>

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

public void saveUser(User user) {
getHibernateTemplate().saveOrUpdate(user);
}

public void removeUser(String userid) {
User user = getUser(userid);
getHibernateTemplate().delete(user);
}

Name and version of the database you are using:MySQL 4.1.11

Hi guys,

I got a User class, which has many-to-many relationship with it role and the java file is like below:

public class User implements Serializable{
protected String id;
protected Set roles = new HashSet();
/**
* @return Returns the id.
* @hibernate.id column="USERID"
* unsaved-value="null"
* generator-class="assigned"
* length="20"
* unique="true"
*/
public String getId() {
return id;
}
/**
* @param id The id to set.
*/
public void setId(String id) {
this.id = id;
}

/**
* Returns the user's roles.
*
* @return Set
*
* @hibernate.set table="user_role" cascade="save-update" lazy="false"
* @hibernate.collection-key column="id"
* @hibernate.collection-many-to-many class="com.stufftolet.model.businessobject.Role"
* column="rolename"
*/
public Set getRoles() {
return roles;
}
/**
* Sets the roles.
*
* @param roles The roles to set
*/
public void setRoles(Set roles) {
this.roles = roles;
}
/**
* Adds a role for the user
*
* @param rolename
*/
public void addRole(Role role) {
getRoles().add(role);
}

}

I am able to add the user role when inserting a new user. But I got a problem of removing and updating the user role. Pls advice, Thanks !

regards,
Mark


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 16, 2005 10:10 am 
Senior
Senior

Joined: Tue Feb 08, 2005 5:26 pm
Posts: 157
Location: Montréal, Québec - Canada
Hi, I am not sure if I understand your problem correctly:

What are you not able to do:
    Removing the association between a User and a Role?
    Modifying the attributes of a Role?
    Modifying a Role associated to a User and saving it by saving the user?


Could you post an example of the code that is not working for you? (ie your testcase)

Thanks ;)
Vincent

_________________
Vincent Giguère
J2EE Developer


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 17, 2005 11:08 am 
Regular
Regular

Joined: Mon Aug 02, 2004 9:33 am
Posts: 69
Hi,

I use the below code to update user:

try {
List tmp = new ArrayList();
tmp = this.userDao.getUserByActivateCode(activateCode);
User usr = new User();

if(tmp.size() > 0){

usr = (User)tmp.get(0);

usr.getRoles().clear();
usr.addRole(new Role(Constant.USER_ROLE_ACTIVE));

Calendar cal = new GregorianCalendar();
//set the activate date
usr.setActivateDate(cal);
//update user
userDao.updateUser(usr);
}

as u can see, I tried to clear the Set then add a new role to the Set again then update it ! But I got the following exception:


[junit] (util.JDBCExceptionReporter 57 ) SQL Error: 1062, SQLState: 23000
[junit] (util.JDBCExceptionReporter 58 ) Duplicate key or integrity constraint violation, message from server: "Duplicate entry 'ACTIVE' for key 1"
[junit] (util.JDBCExceptionReporter 57 ) SQL Error: 1062, SQLState: 23000
[junit] (util.JDBCExceptionReporter 58 ) Duplicate key or integrity constraint violation, message from server: "Duplicate entry 'ACTIVE' for key 1"
[junit] (impl.SessionImpl 2400) Could not synchronize database state with session

[junit] Caused by: java.sql.BatchUpdateException: Duplicate key or integrity constraint violation, message from server: "Duplicate entry 'ACTIVE' for key 1"


Pls help, Thanks !

regards,
Mark


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 17, 2005 1:45 pm 
Senior
Senior

Joined: Tue Feb 08, 2005 5:26 pm
Posts: 157
Location: Montréal, Québec - Canada
It looks like your problem does not come from your mapping. This error is thrown by your database because you have a constraint violation on a table.

I do not have your data schema , so I can only guess, but it looks like the table -role- has a column called -key1- and there is a constraint on it. Either it is set to be a primary key, or you have a uniqueness constraint on it. You are setting the value of this column to ACTIVE and this constraint is broken.

Maybe, your the Constructor of Role is assigning the parameter you are passing to your primary key (id) field by mistake.
Quote:
pulic Role(int activationCode)
{
this.id = activationCode;
}


If you can not find it, you can post your database table schema and I can help you with that.

By the way, you should not instanciate objects in variables if you are not going to use it (like the tmp, user and date variables). The following code will probably be more efficient
Code:

List tmp = this.userDao.getUserByActivateCode(activateCode);
if(tmp.size() > 0)
{
   User usr = (User)tmp.get(0);
   usr.getRoles().clear();
   usr.addRole(new Role(Constant.USER_ROLE_ACTIVE));
   usr.setActivateDate(new GregorianCalendar());
   userDao.updateUser(usr);
}


Let me know if I am right about the error.

Good luck,
Vincent.

_________________
Vincent Giguère
J2EE Developer


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 18, 2005 11:56 am 
Regular
Regular

Joined: Mon Aug 02, 2004 9:33 am
Posts: 69
Hi,

My user table is like below:

<dataset>

<table name='users'>
<column>userid</column>
<column>version</column>
<column>ACTIVATE_CODE</column>
<column>ACTIVATE_DATE</column>
<column>EMAIL</column>
<column>FIRSTNAME</column>
<column>MIDDLENAME</column>
<column>LASTNAME</column>
<column>LAST_LOGIN_DATE</column>
<column>PASSWD</column>
<column>REGISTER_DATE</column>
<column>SECRET_ANSWER</column>
<column>FK_SECRETQUESTION_ID</column>
<column>ADDRESS</column>
<column>AREA</column>
<column>BUILDINGNAME</column>
<column>CITY</column>
<column>FK_COUNTRY_ID</column>
<column>REGION</column>
<column>ROADNAME</column>
<column>ZIPCODE</column>
</table>

<table name='role'>
<column>name</column>
<column>description</column>
<column>version</column>
</table>

<table name='user_role'>
<column>id</column>
<column>rolename</column>
</table>

<dataset>


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 18, 2005 2:20 pm 
Senior
Senior

Joined: Tue Feb 08, 2005 5:26 pm
Posts: 157
Location: Montréal, Québec - Canada
I would really need the database schema (with the Create Table statements) to help you debug.

Prior to that, could you verify if I was right in my last posting:

Quote:
It looks like your problem does not come from your mapping. This error is thrown by your database because you have a constraint violation on a table.

I do not have your data schema , so I can only guess, but it looks like the table -role- has a column called -key1- and there is a constraint on it. Either it is set to be a primary key, or you have a uniqueness constraint on it. You are setting the value of this column to ACTIVE and this constraint is broken.

Maybe, your the Constructor of Role is assigning the parameter you are passing to your primary key (id) field by mistake.


The error is not coming from hibernate.
Quote:
Duplicate key or integrity constraint violation, message from server: "Duplicate entry 'ACTIVE' for key 1"

The database is telling you that you have a key called ->key 1<- that should be unique, and you are inserting a row which does not respect the uniqueness of the column.

Please read my last posting. I think the error is in your java class constructor.

_________________
Vincent Giguère
J2EE Developer


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 18, 2005 4:20 pm 
Expert
Expert

Joined: Mon Feb 14, 2005 12:32 pm
Posts: 609
Location: Atlanta, GA - USA
prettyhandling wrote:
Hi,

I use the below code to update user:

usr = (User)tmp.get(0);
usr.getRoles().clear();
usr.addRole(new Role(Constant.USER_ROLE_ACTIVE));



The problem might be with the code above. I think Hibernate orders delete's last when batching SQL statements and is therefore trying to INSERT the new Role(Constant.USER_ROLE_ACTIVE) before deleting any roles from the clear statement.

You can just execute user.addRole(...) and implement the Role.equals() Role.hashCode() methods so that if the Role already exists(using the business key) in the Set, it is ignored.


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 18, 2005 11:15 pm 
Regular
Regular

Joined: Mon Aug 02, 2004 9:33 am
Posts: 69
Hi,

The table 'user_role' has an existing role, which is REGISTER. So I tried to clear/remove the previous role then insert a new role to it, which is ACTIVE. The role Active is not exist ! Then I got the error msg MySQL 4.1.11 database. So how can I firstly remove the existing role then add a new role to it? Thanks !

regards,
prettyhandling



pksiv wrote:
prettyhandling wrote:
Hi,

I use the below code to update user:

usr = (User)tmp.get(0);
usr.getRoles().clear();
usr.addRole(new Role(Constant.USER_ROLE_ACTIVE));



The problem might be with the code above. I think Hibernate orders delete's last when batching SQL statements and is therefore trying to INSERT the new Role(Constant.USER_ROLE_ACTIVE) before deleting any roles from the clear statement.

You can just execute user.addRole(...) and implement the Role.equals() Role.hashCode() methods so that if the Role already exists(using the business key) in the Set, it is ignored.


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 18, 2005 11:19 pm 
Regular
Regular

Joined: Mon Aug 02, 2004 9:33 am
Posts: 69
Hi,

The table 'user_role' has an existing role, which is REGISTER. So I tried to clear/remove the previous role then insert a new role to it, which is ACTIVE. The role Active is not exist ! Then I got the error msg MySQL 4.1.11 database. So how can I firstly remove the existing role then add a new role to it? Thanks !

regards,
prettyhandling



pksiv wrote:
prettyhandling wrote:
Hi,

I use the below code to update user:

usr = (User)tmp.get(0);
usr.getRoles().clear();
usr.addRole(new Role(Constant.USER_ROLE_ACTIVE));



The problem might be with the code above. I think Hibernate orders delete's last when batching SQL statements and is therefore trying to INSERT the new Role(Constant.USER_ROLE_ACTIVE) before deleting any roles from the clear statement.

You can just execute user.addRole(...) and implement the Role.equals() Role.hashCode() methods so that if the Role already exists(using the business key) in the Set, it is ignored.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 19, 2005 11:27 am 
Regular
Regular

Joined: Mon Aug 02, 2004 9:33 am
Posts: 69
Hi vigi,

The sql code is like below:

create table user_role (
id varchar(20) not null,
rolename varchar(20) not null,
primary key (id, rolename)
)
create table Users (
USERID varchar(20) not null,
version integer not null,
ACTIVATE_CODE varchar(10) unique,
ACTIVATE_DATE datetime,
EMAIL varchar(50) unique,
FIRSTNAME varchar(50),
LAST_LOGIN_DATE datetime,
LASTNAME varchar(255),
MIDDLENAME varchar(50),
PASSWD varchar(50) not null,
REGISTER_DATE datetime,
SECRET_ANSWER varchar(50) not null,
FK_SECRETQUESTION_ID TINYINT(1),
ADDRESS varchar(255),
AREA varchar(50),
BUILDINGNAME varchar(50),
CITY varchar(50),
FK_COUNTRY_ID varchar(3) not null,
FK_REGION_ID varchar(10),
ROADNAME varchar(50),
ZIPCODE varchar(10),
primary key (USERID)
)

create table Role (
NAME varchar(20) not null,
version integer not null,
DESCRIPTION varchar(250),
primary key (NAME)
)

Pls help, Thanks !


vgiguere wrote:
I would really need the database schema (with the Create Table statements) to help you debug.

Prior to that, could you verify if I was right in my last posting:

Quote:
It looks like your problem does not come from your mapping. This error is thrown by your database because you have a constraint violation on a table.

I do not have your data schema , so I can only guess, but it looks like the table -role- has a column called -key1- and there is a constraint on it. Either it is set to be a primary key, or you have a uniqueness constraint on it. You are setting the value of this column to ACTIVE and this constraint is broken.

Maybe, your the Constructor of Role is assigning the parameter you are passing to your primary key (id) field by mistake.


The error is not coming from hibernate.
Quote:
Duplicate key or integrity constraint violation, message from server: "Duplicate entry 'ACTIVE' for key 1"

The database is telling you that you have a key called ->key 1<- that should be unique, and you are inserting a row which does not respect the uniqueness of the column.

Please read my last posting. I think the error is in your java class constructor.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 19, 2005 11:42 am 
Regular
Regular

Joined: Mon Aug 02, 2004 9:33 am
Posts: 69
Hi vgiguere,

The sql code looks like below:


create table Role (
NAME varchar(20) not null,
version integer not null,
DESCRIPTION varchar(250),
primary key (NAME)
)

create table Users (
USERID varchar(20) not null,
version integer not null,
ACTIVATE_CODE varchar(10) unique,
ACTIVATE_DATE datetime,
EMAIL varchar(50) unique,
FIRSTNAME varchar(50),
LAST_LOGIN_DATE datetime,
LASTNAME varchar(255),
MIDDLENAME varchar(50),
PASSWD varchar(50) not null,
REGISTER_DATE datetime,
SECRET_ANSWER varchar(50) not null,
FK_SECRETQUESTION_ID TINYINT(1),
ADDRESS varchar(255),
AREA varchar(50),
BUILDINGNAME varchar(50),
CITY varchar(50),
FK_COUNTRY_ID varchar(3) not null,
FK_REGION_ID varchar(10),
ROADNAME varchar(50),
ZIPCODE varchar(10),
primary key (USERID)
)

create table user_role (
id varchar(20) not null,
rolename varchar(20) not null,
primary key (id, rolename)
)

alter table user_role add index FK143BF46AF027D001 (rolename), add constraint FK143BF46AF027D001 foreign key (rolename) references Role (NAME)
alter table user_role add index FK143BF46AD1B (id), add constraint FK143BF46AD1B foreign key (id) references Users (USERID)

pls help, Thanks !


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 21, 2005 2:20 pm 
Senior
Senior

Joined: Tue Feb 08, 2005 5:26 pm
Posts: 157
Location: Montréal, Québec - Canada
As I wrote in an earlier message, I guess that when you do this:
Code:
new Role(Constant.USER_ROLE_ACTIVE);

You assign the constant: Constant.USER_ROLE_ACTIVE to your Role.name attribute (in your Role() constructor).

But, on your database table, you have set the primary key on the attribute NAME:
Code:
create table Role (
NAME varchar(20) not null,
version integer not null,
DESCRIPTION varchar(250),
primary key (NAME)
)


When you do:
Code:
usr.addRole(new Role(Constant.USER_ROLE_ACTIVE));
you create a NEW instance of Role, which will be inserted in the database. Its Column NAME will be set to ACTIVE (The value of Constant.USER_ROLE_ACTIVE). But this is the primary key of the table and A primary key can not be duplicated!

This is why the database is sending you the message:
Quote:
Duplicate key or integrity constraint violation, message from server: "Duplicate entry 'ACTIVE' for key 1"


Have a good day,
Vincent

_________________
Vincent Giguère
J2EE Developer


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