开发者

IllegalArgumentException in class: ..., getter method of property: id

I have two classes Role and Privilege with the relation ManyToMany. When adding a Privilege to a Role, and then calling saveOrUpdate(role), I get the exception below.

Here is the Role class:

@Entity
@Table(name = "ROLES")
public class Role implements GenericDomain {

    private static final long serialVersionUID = -7620550658984151796L;

    private Long    id;
    private String  code;
    private String  name;

    private Set<User> users = new HashSet<User>(0);
    private Set<Privilege> privileges = new HashSet<Privilege>(0);

    public Role() {
    }

    public Role(String code, String name) {
        this.code = code;
        this.name = name;
    }


    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name = "ID")
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    @Column(name = "CODE", unique = true, nullable = false, length = 16)
    @NotEmpty(message= "password.required")
    @Length(min = 3, max = 16)
    public String getCode() { return code; }
    public void setCode(String code) { this.code = code; }

    @Column(name="NAME", nullable = false, length = 64)
    @NotEmpty
    @Length(min = 1, max = 32)
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name = "ROLES_PRIVILEGES"
        , joinColumns = { @JoinColumn(name = "ROLE_ID") }
        , inverseJoinColumns = { @JoinColumn(name = "PRIVILEGE_ID") }
    )

    public Set<Privilege> getPrivileges() {
        return this.privileges;
    }
    public void setPrivileges(Set<Privilege> privileges) {
        this.privileges = privileges;
    }
    /*  overide of hascode, equals*/ 
}

Here is the Privilege class:

@Entity
@Table(name = "PRIVILEGES")
public class Privilege implements GenericDomain {

    private static final long serialVersionUID = 4649689934972816194L;

    private Long    id;
    private String  code;

    private Set<Role> roles = new HashSet<Role>(0);

    public Privilege() {
    }

    public Privilege(String code) {
        this.code = code;
    }

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name = "ID")
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    @Column(name = "CODE", unique = true, nullable = false, length = 16)
    @NotEmpty(message= "password.required")
    @Length(min = 3, max = 16)
    public String getCode() { return code; }
    public void setCode(String code) { this.code = code; }

    @ManyToMany(cascade=CascadeType.REFRESH, mappedBy="privileges开发者_如何学编程")
    public Set<Role> getRoles() {
        return this.roles;
    }
    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }

    /*overide equals and hascode*/
}

And here is the the exception:

 IllegalArgumentException in class: com.stunaz.domain.Privilege, getter method of property: id
 ....
 javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.stunaz.domain.Privilege.id
 ....
 java.lang.IllegalArgumentException: object is not an instance of declaring class

It seems something is wrong with my mapping, that somewhere I should pass an object but I am passing an Id.


Hibernate is not much user friendly when it comes to telling user what's wrong with mapping.

Solution:

  1. Debug the app
  2. Set a breakpoint for the event of IllegalArgumentException being thrown (anywhere)
  3. Perform the operation which causes this
  4. Go up through the call stack and inspect the active stack variables.

Using this procedure, I figured out what was wrong with my mapping.

In general, from what I have seen, it's usually wrong class explicitely stated somewhere, like @MapKeyClass(Wrong.class) when the key is actually String etc.

Or, calling wrong (Hibernate) API, like setParameter() instead of setParameterList():

Query query = session.getNamedQuery(queryName);  
// org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter
query.setParameter("children", aCollectionOfChildren);
query.list();

Or, in case of Criteria API, I have seen this:

DetachedCriteria crit = DetachedCriteria.forClass( Group.class ); crit.add( Restrictions.eq( "parent", id ) );

The getParent() method of Group returns a Group but I was attempting to compare it against a Long.


To get an illegal argument exception calling the getId() method, it seems that Hibernate thinks the type of your id is something other than Long (probably Integer). Maybe try adding @Type(type="long") to your ids.

Whenever I have weird issues with Hibernate, I always attach the source code and debug around where the error happens. This can give you some insight into what Hibernate is trying to do, and help figure out where you may have missed something, or passed a bad argument somewhere.


At first glance your code seems fine except maybe for:

@ManyToMany(cascade=CascadeType.REFRESH, mappedBy="privileges")

I'm not sure if this is incorrect but this is the way I do it:

@ManyToMany(cascade=CascadeType.REFRESH, mappedBy="privileges", targetEntity = Roles.class)

This mappedBy property could even be omitted...


How are you saving/updating this?

Are you getting the 'Role' object for which you want to save the 'Permission' by calling findById(Long roleId)? Once you get that role object create a new Permission object and setRole(role) and set other properties and callthe saveOrUpdate(permission)? That should work.


Just a note for others although this might be not related to this problem. It happened to me that I was mapping a DTO coming from a REST API to an Entity. One of the child DTOs was not mapped correctly to a child Entity (I was using Dozer). Hibernate failed because the id of the DTO was not compatible with the id of the Entity.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜