-->
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.  [ 6 posts ] 
Author Message
 Post subject: ids for this class must be manually assigned before calling
PostPosted: Fri Mar 23, 2007 12:33 pm 
Newbie

Joined: Fri Mar 23, 2007 12:13 pm
Posts: 3
Hi,

I'm using Hibernate 3.2.2ga with Annotations and, when I try to persist an object, I get the following error:

Code:
Exception in thread "AWT-EventQueue-0" javax.persistence.PersistenceException: org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): presenca.Aluno
        at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:629)
        at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:218)




Ok, I've read a lot of posts about this kind of problem, saying that they have Ids that require to be manual assigned but they are not providing it. Well, that's not my case, because I'm setting it before calling persist(). My ID (PK) column in database is the RA column. As one can see, it is being set prior to persist() by setRA() method.

My table description (mySql DB)

Code:
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| RA    | int(11)     | NO   | PRI |         |       |
| Nome  | varchar(50) | NO   |     |         |       |
| Email | varchar(80) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+


My entity class:

Code:
package presenca;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

/**
* Entity class Aluno
*
* @author Bruno
*/
@Entity
@Table(name = "aluno")
@NamedQueries( {
        @NamedQuery(name = "Aluno.findByRa", query = "SELECT a FROM Aluno a WHERE a.ra = :ra"),
        @NamedQuery(name = "Aluno.findByNome", query = "SELECT a FROM Aluno a WHERE a.nome = :nome"),
        @NamedQuery(name = "Aluno.findByEmail", query = "SELECT a FROM Aluno a WHERE a.email = :email")
    })
public class Aluno implements Serializable {

    @Id
    @Column(name = "RA", nullable = false, insertable = true)
    private Integer ra;

    @Column(name = "Nome", nullable = false)
    private String nome;

    @Column(name = "Email")
    private String email;
   
    /** Creates a new instance of Aluno */
    public Aluno() {
    }

    /**
     * Creates a new instance of Aluno with the specified values.
     * @param ra the ra of the Aluno
     */
    public Aluno(Integer ra) {
        this.ra = ra;
    }

    /**
     * Creates a new instance of Aluno with the specified values.
     * @param ra the ra of the Aluno
     * @param nome the nome of the Aluno
     */
    public Aluno(Integer ra, String nome) {
        this.ra = ra;
        this.nome = nome;
    }

    /**
     * Gets the ra of this Aluno.
     * @return the ra
     */
    public Integer getRa() {
        return this.ra;
    }

    /**
     * Sets the ra of this Aluno to the specified value.
     * @param ra the new ra
     */
    public void setRa(Integer ra) {
        this.ra = ra;
    }

    /**
     * Gets the nome of this Aluno.
     * @return the nome
     */
    public String getNome() {
        return this.nome;
    }

    /**
     * Sets the nome of this Aluno to the specified value.
     * @param nome the new nome
     */
    public void setNome(String nome) {
        this.nome = nome;
    }

    /**
     * Gets the email of this Aluno.
     * @return the email
     */
    public String getEmail() {
        return this.email;
    }

    /**
     * Sets the email of this Aluno to the specified value.
     * @param email the new email
     */
    public void setEmail(String email) {
        this.email = email;
    }

    /**
     * Returns a hash code value for the object.  This implementation computes
     * a hash code value based on the id fields in this object.
     * @return a hash code value for this object.
     */
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (this.ra != null ? this.ra.hashCode() : 0);
        return hash;
    }

    /**
     * Determines whether another object is equal to this Aluno.  The result is
     * <code>true</code> if and only if the argument is not null and is a Aluno object that
     * has the same id field values as this object.
     * @param object the reference object with which to compare
     * @return <code>true</code> if this object is the same as the argument;
     * <code>false</code> otherwise.
     */
    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Aluno)) {
            return false;
        }
        Aluno other = (Aluno)object;
        if (this.ra != other.ra && (this.ra == null || !this.ra.equals(other.ra))) return false;
        return true;
    }

    /**
     * Returns a string representation of the object.  This implementation constructs
     * that representation based on the id fields.
     * @return a string representation of the object.
     */
    @Override
    public String toString() {
        return "presenca.Aluno[ra=" + ra + "]";
    }
   
}


And my calling method:

Code:
    private void criaNovoAluno() {
        initEntityManager();
       
        em.getTransaction().begin();
        Aluno novoAluno = new Aluno();
        novoAluno.setRa(Integer.getInteger(jTextFieldRA.getText()));
        novoAluno.setNome(jTextFieldNome.getText());
        novoAluno.setEmail(jTextFieldEmail.getText());
        em.persist(novoAluno); // THIS LINE THROWS THE EXCEPTION
        em.getTransaction().commit();
    }



I'm a newbie on JPA, so I might be doing something wrong,, but I just can't tell what. I believe the entity class is defined correctly, since it was generated by NetBeans 5.5. Any help is appreciate.

Regards,
Bruno.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 23, 2007 1:00 pm 
Expert
Expert

Joined: Tue Dec 28, 2004 7:02 am
Posts: 573
Location: Toulouse, France
You should verify that your code:
Integer.getInteger(jTextFieldRA.getText())
does not return null. The error is clearly that: assigned identifiers are the one you have to set manually.

About this: are you forced to use manually assigned identifiers? They're not the best hibernate/JPA practices.

_________________
Baptiste
PS : please don't forget to give credits below if you found this answer useful :)


Top
 Profile  
 
 Post subject: Yes, it was returning null!
PostPosted: Fri Mar 23, 2007 2:28 pm 
Newbie

Joined: Fri Mar 23, 2007 12:13 pm
Posts: 3
Batmat,

You hit the bull's eye! Is was returning null, in fact.

About this ID being manualy generated, it is a kind of "SSN", so I want the user to type it. You've said it is not a good practice to manualy assign them. I didn't know that, can you explain me why or point a place where I can find more about these practices?

Thank you very much for the assistance.

Regards,
Bruno.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 24, 2007 8:02 am 
Expert
Expert

Joined: Tue Dec 28, 2004 7:02 am
Posts: 573
Location: Toulouse, France
In fact, it's recommended to define what's called a surrogate key. This key will be automatically assigned (see the different generators, for you "native" would be certainly the right choice. What's your db by the way?).

Using non business keys is recommended because it mainly lets you schema evolve more easily: imagine you want to update your business key, you will have to also update every foreign keys referencing it...

See http://www.hibernate.org/hib_docs/v3/re ... -practices :
Quote:
Declare identifier properties on persistent classes.

Hibernate makes identifier properties optional. There are all sorts of reasons why you should use them. We recommend that identifiers be 'synthetic' (generated, with no business meaning).

_________________
Baptiste
PS : please don't forget to give credits below if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 26, 2007 1:02 pm 
Newbie

Joined: Fri Mar 23, 2007 12:13 pm
Posts: 3
Batmat,

I'm now using MySql 5, but I'm trying to develop a sort of "db independent" application, i.e., could use it with MySql, DB2, Oracle, SQL Server, etc. In the case of MySql I should probably use autoincrement as PK, or those surrogate keys would go just on my app?

Thanks for the references!

Regards,
Bruno.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 26, 2007 1:17 pm 
Expert
Expert

Joined: Tue Dec 28, 2004 7:02 am
Posts: 573
Location: Toulouse, France
Using generator="native" will use the right strategy according to the Dialect (autoincrement for MySQL, sequence for postgreSQL, identity for HSQL, and so on).

_________________
Baptiste
PS : please don't forget to give credits below if you found this answer useful :)


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