Hibernate + MySQL com comportamento muito estranho

Olá pessoal,

Comecei a usar Hibernate há uns dias, e tô enroscado num problema que parece muito estranho!

Segui os seguintes passos:

  1. Criei 2 tabelas usaindo MySQL Workbench: User e UserClass. user contem uma chave estranheira pra UserClass.
  2. Criei um app de teste pra validar a utilização básica do Hibernate.

Coisas estranhas acontecem:

  1. Após executar o app, minha base muda… A campo ID do user misteriosamente desaparece. Consequentemente não consigo recuperar o ID dos Users inseridos (veja o output abaixo).
  2. A chave estrangeira na tabela Users é substituida por uma outra gerada pelo Hibernate.
  3. Daí prabaixo é de se esperar que mais nada funcione direito.

Output:

0 - Flushing DB: Hibernate: select user0_.username as username0_, user0_.password as password0_, user0_.blocked as blocked0_, user0_.user_class_id as user4_0_ from user user0_ Hibernate: select userclass0_.id_user_class as id1_1_, userclass0_.permissions as permissi2_1_, userclass0_.title as title1_ from lojatest.userclass userclass0_ 1 - Creating UserClasses: Hibernate: insert into lojatest.userclass (permissions, title) values (?, ?) Hibernate: insert into lojatest.userclass (permissions, title) values (?, ?) Hibernate: insert into lojatest.userclass (permissions, title) values (?, ?) 2 - Retrieving UserClasses: Hibernate: select userclass0_.id_user_class as id1_1_, userclass0_.permissions as permissi2_1_, userclass0_.title as title1_ from lojatest.userclass userclass0_ Found 3 UserClasses: ID: 1 Title: UserClass 1 Permissions: AGKL ID: 2 Title: UserClass 2 Permissions: BCDEF ID: 3 Title: UserClass 3 Permissions: XYZ 3 - Creating Users: Hibernate: insert into user (password, blocked, user_class_id, username) values (?, ?, ?, ?) Hibernate: insert into user (password, blocked, user_class_id, username) values (?, ?, ?, ?) Hibernate: insert into user (password, blocked, user_class_id, username) values (?, ?, ?, ?) Hibernate: insert into user (password, blocked, user_class_id, username) values (?, ?, ?, ?) Hibernate: insert into user (password, blocked, user_class_id, username) values (?, ?, ?, ?) Hibernate: insert into user (password, blocked, user_class_id, username) values (?, ?, ?, ?) Inserted: 0 0 0 0 0 0 4 - Retrieving Users: Hibernate: select user0_.username as username0_, user0_.password as password0_, user0_.blocked as blocked0_, user0_.user_class_id as user4_0_ from user user0_ Found 6 Users: UserName: User 1 Password: Password 1 Blocked: false UserClass: UserClass 1 (1) UserName: User 2 Password: Password 2 Blocked: false UserClass: UserClass 2 (2) UserName: User 3 Password: Password 3 Blocked: false UserClass: UserClass 3 (3) UserName: User 4 Password: Password 4 Blocked: false UserClass: UserClass 1 (1) UserName: User 5 Password: Password 5 Blocked: false UserClass: UserClass 2 (2) UserName: User 6 Password: Password 6 Blocked: false UserClass: UserClass 3 (3) 5 - Deleting Users ("User 0" and "User 0"): Hibernate: select user0_.username as username0_0_, user0_.password as password0_0_, user0_.blocked as blocked0_0_, Exception in thread "main" java.lang.IllegalArgumentException: attempt to create delete event with null entity user0_.user_class_id as user4_0_0_ from user user0_ where user0_.username=? at org.hibernate.event.DeleteEvent.<init>(DeleteEvent.java:47) at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:926) at netbeansproject.Main.testUserClassAndUsers(Main.java:142) at netbeansproject.Main.main(Main.java:260)

Alguém tem alguma idéia do pq isso acontece?

Muito obrigado pela ajuda.

Meu setup é:

Libs adicionadas ao proj:

  • mysql-connector-java-5.1.13-bin.jar
  • antlr-2.7.6.jar
  • commons-collections-3.1.jar
  • dom4j-1.6.1.jar
  • javassist-3.9.0.GA.jar
  • hibernate-testing.jar
  • hibernate3.jar
  • jta-1.1.jar
  • slf4j-api-1.5.8.jar
  • c3p0-0.9.1.jar
  • ehcache-1.5.0.jar
  • infinispan-core-4.0.0.FINAL.jar
  • jbosscache-core-3.2.1.GA.jar
  • cglib-2.2.jar
  • oscache-2.1.jar
  • proxool-0.8.3.jar
  • swarmcache-1.0RC2.jar
  • hibernate-jpa-2.0-api-1.0.0.Final.jar
  • slf4j-jdk14-1.5.8.jar

Código importante:
User.java:

[code]package domain;

import javax.persistence.*;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

@Entity
@Table(name = “user”, schema = “lojatest”)
public class User {

@Id @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="id_user")
private int id;

@Column(unique = true, nullable = false, insertable = true, updatable = false)
private String userName;

@Column(unique = false, nullable = false, insertable = true, updatable = true)
private String password;

private Boolean blocked;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "id_user_class", insertable = true, updatable = true)
@Fetch(FetchMode.JOIN)
@Cascade(CascadeType.SAVE_UPDATE)
private UserClass userClass;

public User() {
}

public int getId() {
    return this.id;
}

public void setId(int id) {
    this.id = id;
}

public String getUserName() {
    return this.userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

public String getPassword() {
    return this.password;
}

public void setPassword(String password) {
    this.password = password;
}

public Boolean getBlocked() {
    return this.blocked;
}

public void setBlocked(Boolean blocked) {
    this.blocked = blocked;
}

public UserClass getUserClass() {
    return this.userClass;
}

public void setUserClass(UserClass userClass) {
    this.userClass = userClass;
}

}
[/code]

UserClass.java:

[code]package domain;

import java.util.Collection;
import java.util.HashSet;

import javax.persistence.*;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

@Entity
@Table(name = “userclass”, schema = “lojatest”)
public class UserClass {

@Id @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="id_user_class")
private int id;

@Column(unique = true, nullable = false, insertable = true, updatable = true)
private String title;

private String permissions;

@OneToMany(mappedBy = "userClass", fetch = FetchType.LAZY)
@Cascade(CascadeType.DELETE)
private Collection<User> users = new HashSet<User>();

public UserClass() {
}

public int getId() {
    return this.id;
}

public void setId(int id) {
    this.id = id;
}

public String getTitle() {
    return this.title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getPermissions() {
    return permissions;
}

public void setPermissions(String permissions) {
    this.permissions = permissions;
}

public void setUsers(Collection users) {
    this.users = users;
}

public Collection getUsers() {
    return this.users;
}

public void addUser(User user) {
    user.setUserClass(this);
    this.users.add(user);
}

}
[/code]

DatabaseFactory.java:

[code]package Database;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class DatabaseFactory {

private static DatabaseFactory instance = null;

private SessionFactory sessionFactory;

public static DatabaseFactory getInstance() {
    if (DatabaseFactory.instance == null) {
        DatabaseFactory.instance = new DatabaseFactory().init();
    }

    return DatabaseFactory.instance;
}

public SessionFactory getSessionFactory() {
    return this.sessionFactory;
}

public Session getSession() {
    return this.sessionFactory.openSession();
}

private DatabaseFactory init() {
    Configuration cfg = new Configuration();

    cfg.addClass(domain.UserClass.class);
    cfg.addClass(domain.User.class);

    cfg.setProperties(System.getProperties());
    cfg.configure();
    SessionFactory sessions = cfg.buildSessionFactory();

    sessionFactory = cfg.configure().buildSessionFactory();
    return this;
}

}
[/code]

Main.java:

[code]package netbeansproject;

import Database.DatabaseFactory;
import domain.*;

import java.util.List;
import java.util.Iterator;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class Main {
public void testUserClassAndUsers() {
System.out.println(“Testing Users and UserClasses…”);

    Session newSession = DatabaseFactory.getInstance().getSession();

    System.out.println("0 - Flushing DB:");
    Transaction t0 = newSession.beginTransaction();
    Query query00 = newSession.createQuery("from User as user");
    List list00 = query00.list();
    Iterator iter00 = list00.iterator();
    while(iter00.hasNext()) {
        User user = (User)iter00.next();
        System.out.println("    Deleting User: " + user.getUserName());
        newSession.delete(user);
    }
    Query query01 = newSession.createQuery("from UserClass as userClass");
    List list01 = query01.list();
    Iterator iter01 = list01.iterator();
    while(iter01.hasNext()) {
        UserClass userClass = (UserClass)iter01.next();
        System.out.println("    Deleting UserClass: " + userClass.getId());
        newSession.delete(userClass);
    }
    t0.commit();

    System.out.println("1 - Creating UserClasses:");
    Transaction t1 = newSession.beginTransaction();
    UserClass uc1 = new UserClass();
    uc1.setTitle("UserClass 1");
    uc1.setPermissions("AGKL");
    newSession.save(uc1);

    UserClass uc2 = new UserClass();
    uc2.setTitle("UserClass 2");
    uc2.setPermissions("BCDEF");
    newSession.save(uc2);

    UserClass uc3 = new UserClass();
    uc3.setTitle("UserClass 3");
    uc3.setPermissions("XYZ");
    newSession.save(uc3);
    t1.commit();

    System.out.println("2 - Retrieving UserClasses:");
    Transaction t2 = newSession.beginTransaction();
    Query query1 = newSession.createQuery("from UserClass as userClass");
    List list1 = query1.list();
    t2.commit();
    System.out.println("    Found " + list1.size() + " UserClasses:");
    Iterator iter1 = list1.iterator();
    while(iter1.hasNext()) {
        UserClass userClass = (UserClass)iter1.next();
        System.out.println("        ID:              " + userClass.getId());
        System.out.println("            Title:       " + userClass.getTitle());
        System.out.println("            Permissions: " + userClass.getPermissions());
    }

    System.out.println("3 - Creating Users:");
    Transaction t3 = newSession.beginTransaction();
    User u1 = new User();
    u1.setUserName("User 1");
    u1.setPassword("Password 1");
    u1.setBlocked(false);
    u1.setUserClass(uc1);
    newSession.save(u1);

    User u2 = new User();
    u2.setUserName("User 2");
    u2.setPassword("Password 2");
    u2.setBlocked(false);
    u2.setUserClass(uc2);
    newSession.save(u2);

    User u3 = new User();
    u3.setUserName("User 3");
    u3.setPassword("Password 3");
    u3.setBlocked(false);
    u3.setUserClass(uc3);
    newSession.save(u3);

    User u4 = new User();
    u4.setUserName("User 4");
    u4.setPassword("Password 4");
    u4.setBlocked(false);
    u4.setUserClass(uc1);
    newSession.save(u4);

    User u5 = new User();
    u5.setUserName("User 5");
    u5.setPassword("Password 5");
    u5.setBlocked(false);
    u5.setUserClass(uc2);
    newSession.save(u5);

    User u6 = new User();
    u6.setUserName("User 6");
    u6.setPassword("Password 6");
    u6.setBlocked(false);
    u6.setUserClass(uc3);
    newSession.save(u6);
    t3.commit();

    int u1id = u1.getId();
    int u2id = u2.getId();
    int u3id = u3.getId();
    int u4id = u4.getId();
    int u5id = u5.getId();
    int u6id = u6.getId();
    System.out.println("    Inserted: " + u1id + " " + u2id + " " + u3id + " " + u6id + " " + u5id + " " + u6id);


    System.out.println("4 - Retrieving Users:");
    Transaction t4 = newSession.beginTransaction();
    Query query2 = newSession.createQuery("from User as user");
    List list2 = query2.list();
    t4.commit();
    System.out.println("    Found " + list2.size() + " Users:");
    Iterator iter2 = list2.iterator();
    while(iter2.hasNext()) {
        User user = (User)iter2.next();
        System.out.println("        UserName:      " + user.getUserName());
        System.out.println("            Password:  " + user.getPassword());
        System.out.println("            Blocked:   " + user.getBlocked());
        System.out.println("            UserClass: " + user.getUserClass().getTitle() + " (" + user.getUserClass().getId() + ")");
    }

    System.out.println("5 - Deleting Users (\"User " + u1id + "\" and \"User " + u3id + "\"):");
    Transaction t5 = newSession.beginTransaction();
    newSession.delete(newSession.get(User.class, Integer.toString(u1id)));
    newSession.delete(newSession.get(User.class, Integer.toString(u3id)));
    t5.commit();

    System.out.println("6 - Retrieving Users:");
    Transaction t6 = newSession.beginTransaction();
    Query query3 = newSession.createQuery("from User as user");
    List list3 = query3.list();
    t6.commit();
    System.out.println("    Found " + list3.size() + " Users:");
    Iterator iter3 = list3.iterator();
    while(iter3.hasNext()) {
        User user = (User)iter3.next();
        System.out.println("        UserName:      " + user.getUserName());
        System.out.println("            Password:  " + user.getPassword());
        System.out.println("            Blocked:   " + user.getBlocked());
        System.out.println("            UserClass: " + user.getUserClass().getTitle() + " (" + user.getUserClass().getId() + ")");
    }

    System.out.println("7 - Deleting UserClass (\"UserClass 3\"):");
    Transaction t7 = newSession.beginTransaction();
    newSession.delete(uc3);
    t7.commit();

    System.out.println("8 - Retrieving UserClasses:");
    Transaction t8 = newSession.beginTransaction();
    Query query4 = newSession.createQuery("from UserClass as userClass");
    List list4 = query4.list();
    t8.commit();
    System.out.println("    Found " + list4.size() + " UserClasses:");
    Iterator iter4 = list4.iterator();
    while(iter4.hasNext()) {
        UserClass userClass = (UserClass)iter4.next();
        System.out.println("        ID:              " + userClass.getId());
        System.out.println("            Title:       " + userClass.getTitle());
        System.out.println("            Permissions: " + userClass.getPermissions());
    }

    System.out.println("9 - Retrieving Users:");
    Transaction t9 = newSession.beginTransaction();
    Query query5 = newSession.createQuery("from User as user");
    List list5 = query5.list();
    t9.commit();
    System.out.println("    Found " + list5.size() + " Users:");
    Iterator iter5 = list5.iterator();
    while(iter5.hasNext()) {
        User user = (User)iter5.next();
        System.out.println("        UserName:      " + user.getUserName());
        System.out.println("            Password:  " + user.getPassword());
        System.out.println("            Blocked:   " + user.getBlocked());
        System.out.println("            UserClass: " + user.getUserClass().getTitle() + " (" + user.getUserClass().getId() + ")");
    }

    newSession.close();
}

public static void main(String[] args) {
    Main instance = new Main();

    instance.testUserClassAndUsers();
}

}
[/code]

Script SQL para criar o banco (gerado pelo MySQL Workbench):

[code]SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=‘TRADITIONAL’;

DROP SCHEMA IF EXISTS LojaTest ;
CREATE SCHEMA IF NOT EXISTS LojaTest ;
SHOW WARNINGS;
USE LojaTest ;


– Table LojaTest.UserClass


DROP TABLE IF EXISTS LojaTest.UserClass ;

SHOW WARNINGS;
CREATE TABLE IF NOT EXISTS LojaTest.UserClass (
id INT UNSIGNED NOT NULL AUTO_INCREMENT ,
title VARCHAR(45) NOT NULL ,
permissions VARCHAR(16) NULL ,
PRIMARY KEY (id) )
ENGINE = InnoDB;

SHOW WARNINGS;
CREATE UNIQUE INDEX id_UNIQUE ON LojaTest.UserClass (id ASC) ;

SHOW WARNINGS;
CREATE UNIQUE INDEX title_UNIQUE ON LojaTest.UserClass (title ASC) ;

SHOW WARNINGS;


– Table LojaTest.User


DROP TABLE IF EXISTS LojaTest.User ;

SHOW WARNINGS;
CREATE TABLE IF NOT EXISTS LojaTest.User (
id INT NOT NULL AUTO_INCREMENT ,
username VARCHAR(10) NOT NULL ,
password VARCHAR(30) NOT NULL ,
blocked TINYINT(1) NOT NULL DEFAULT false ,
userclass_id INT UNSIGNED NOT NULL ,
PRIMARY KEY (id) ,
CONSTRAINT fk_User_UserClass1
FOREIGN KEY (userclass_id )
REFERENCES LojaTest.UserClass (id )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;

SHOW WARNINGS;
CREATE INDEX fk_User_UserClass1 ON LojaTest.User (userclass_id ASC) ;

SHOW WARNINGS;
CREATE UNIQUE INDEX username_UNIQUE ON LojaTest.User (username ASC) ;

SHOW WARNINGS;

SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
[/code]