-->
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.  [ 15 posts ] 
Author Message
 Post subject: org.hibernate.PropertyAccessException (cannot update join)
PostPosted: Sat Jun 28, 2008 12:37 pm 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
hello,

I have 3 tables in my database:

ROLE (ID_ROLE, DESCRIPTION)
ROLE_PERSON (ID_ROLE, ID_PERSON)
PERSON (ID_PERSON, NAME)

and mapped them as a ManyToMany-Relation:

Code:
@Entity
public class Person implements Serializable {

private int idPerson;

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "ID_PERSON", nullable = false, insertable = true, updatable = true)
public int getIdPerson() {
        return idPerson;
    }

public void setIdPerson(int idPerson) {
        this.idPerson = idPerson;
    }
...
private Set<Role> roles = new HashSet<Role>();

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="ROLE_PERSON",
joinColumns= {@JoinColumn (name="ID_PERSON", referencedColumnName="ID_PERSON")},
inverseJoinColumns= {@JoinColumn (name="ID_ROLE", referencedColumnName="ID_ROLE") } )
public Set <Role> getRoles() {
        return roles;
    }

public void setRoles(Set <Roles> roles) {
        this.roles= roles;
    }

..


Code:
@Entity
public class Role {

private Integer idRoles;

@Id
@Column(name = "ID_ROLE", nullable = false)
public Integer getIdRole() {
        return idRole;
    }

public void setIdRoles(Integer idRole) {
        this.idRole= idRole;
    }

private Set<Person> persons= new HashSet<Person>();

@ManyToMany(cascade = CascadeType.ALL, mappedBy="roles")
public Set<Person> getPerson() {
       return persons;
    }

public void setPerson(Set<Person> persons) {
        this.persons= persons;
    }


The relationship works well by doing some HQLs (JPA-QLs). But when I want to persist a new Person-Instance, the following stacktrace occurs:

Code:
Caused by: org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of entity.Role.idRole
   at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:171)
   at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:183)
   at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3591)
   at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:3307)
   at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:181)
   at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:218)
   at org.hibernate.type.EntityType.getIdentifier(EntityType.java:397)
   at org.hibernate.type.EntityType.replace(EntityType.java:253)
   at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:451)
   at org.hibernate.type.CollectionType.replace(CollectionType.java:518)
   at org.hibernate.type.TypeFactory.replace(TypeFactory.java:482)
   at org.hibernate.event.def.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:340)
   at org.hibernate.event.def.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:153)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:126)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
   at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
   at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:227)
   ... 140 more
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:145)
   ... 158 more


This is my session-bean:

Code:
public void persistPerson(Person person)
{

person.setName(this.person.getName());
person.setRoles(this.person.getRoles());
entityManager.persist(person);



This is my view to obtain the list of selected roles (this works):

Code:
<s:label value=Name"/>
<h:inputText value="#{bean.name}" required="true"/>

<s:label value="Select Roles"/>
<h:selectManyCheckbox value="#{users.roles}">
<s:selectItems value="#{bean.rolesList}" var="r" label="#{r.description}" itemValue="#{r.idRole}"/>
</h:selectManyCheckbox>


The persist works only, if the user will not select any roles. Then a person-instance with its name and id will be stored in the database. By persisting any roles within a user, the stacktrace above occurs.

I have tried a lot but I cannot solve the problem.
Any Idea, how I can solve that problem??

Thanks.


Last edited by nimo23 on Mon Jun 30, 2008 4:44 am, edited 2 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 30, 2008 2:36 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
I do not understand, why Hibernate complains that the "object is not an instance of declaring class" when searching the primary key from Table ROLE. I know, Users is my actual instance..but Hibernat cannot save a User-Record without considering the m:n-Relation..I mean, it should save the join-table automatically open a new session for that..

Code:
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 30, 2008 4:53 am 
Senior
Senior

Joined: Tue May 10, 2005 9:00 am
Posts: 125
Hi,

i suggest you investigate this line of code:

Code:
person.setRoles(this.person.getRoles());

It looks like you have two "Person" class, one that is for hibernate, one that is for JSF. I thus suppose you have also 2 "Role" classes, one that is for hibernate, one that is for JSF, isn't it? It seems you put in the Hibernate person a set of JSF roles, which hibernate does not expect to see in your set :)


I would also suggest that you add this line before persisting Person:
Code:
Object o = person.getRoles().iterator().next();
System.out.println("roles in person are of class"+ (o==null?"null":o.getClass().getName()));


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 30, 2008 5:20 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
I use SEAM and I do not have two Person-Role-Classes.

The strange thing is that this works well:

Code:
person.setName(this.person.getName());
person.setAge(this.person.getAge());

entityManager.persist(person);


Hibernate persist a new person-instance! (So I refer right to my instance!)

Adding this the Set of Roles...

Code:
person.setName(this.person.getName());
person.setAge(this.person.getAge());
person.setRoles(this.person.getRoles());
entityManager.persist(person);


...does not work, even the instance of getRoles() is not empty (!), grrr...

Hibernate does not complain illegal types or something like that..so the Set of Roles does work. The only problem is, that Hibernate needs the idRole (for the join-table) and says that this entity (Role) is not an actual instance..even I only persist a new Person-Instance..am I right?

Code:
IllegalArgumentException occurred calling getter of entity.Role.idRole


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 30, 2008 6:20 am 
Senior
Senior

Joined: Tue May 10, 2005 9:00 am
Posts: 125
This
Quote:
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class


and this

Quote:
person.setRoles(this.person.getRoles());


lead me to think you are putting in person.roles something else than a Set of Roles, for whatever reason. Maybe you mixup something somewhere with value binding. Add this code prior to the persist call and tell us what it say:

Code:
person.setRoles(this.person.getRoles());
for (Iterator i = this.person.getRoles().iterator(); it.hasNext();){
    Object o = (Object) i.next();
    System.out.println("Element in set: "+o+": "+o.getClass().getName()),;
}
entityManager.persist(person);


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 30, 2008 6:21 am 
Senior
Senior

Joined: Tue May 10, 2005 9:00 am
Posts: 125
edit: double post


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 30, 2008 8:28 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
yeahh tchize,

I do not know, if u know (use) SEAM..but you are right!

Look at that:
Code:
<!-- Select Roles -->
<h:selectManyCheckbox value="#{person.roles}" >
<s:selectItems value="#{bean.rolesList}" var="m" label="#{r.description}" itemValue="#{r.idRole}"/>
<s:convertEntity/>
</h:selectManyCheckbox>


I had used the tag s:convertEntity..for whatever reason this does not work well and the debugger does only tell me the half truth..

Now, I use this:

Code:
<h:selectManyCheckbox value="#{person.roles}" id="selectMany">
<f:selectItems value="#{bean.rolesList}" var="m" label="#{r.description}" itemValue="#{r.idRole}"/>
</h:selectManyCheckbox>


and it comes out, that you are right:

Code:
Argument Error: An option for component selectMany was not an instance of javax.faces.model.SelectItem. Type found: java.util.ArrayList.


So, I am (newbie:-) and obtain the rolesList as follows:

Code:
public List <SelectItem> getRolesList() {

return  (List <SelectItem>) entityManager.createQuery("from Roles r").getResultList();
   }


How can I solve that type-missmatch?

I also cast the ResultList to (List <SelectItem>), but it does not work.

(Besides, I do not know, why hibernate complains bout an instance, while there is another problem bout the type-mismatch..)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 30, 2008 9:30 am 
Senior
Senior

Joined: Tue May 10, 2005 9:00 am
Posts: 125
Hi,
I do not use SEAM, however i use JSF + Hibernate.

shouldn't you do sometinhg like this?


<s:selectItems value="#{bean.rolesList}" var="r" label="#{r.description}" itemValue="#{r}"/>

I mean, you name each item "m", but you use a variable "r" ?? and you ask seam to store "r.idRole" instead of "r" inside your set. I bet you end with a Set full of Integer instead of a Set full of Role.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 30, 2008 9:59 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
oh.

I use this:

Code:
<s:selectItems value="#{bean.rolesList}" var="m" label="#{m.description}" itemValue="#{m.id}"/>


I show m.description of a row and return m.id to my sessionBean. But my But the failure is still alive:

Code:
Argument Error: An option for component selectMany was not an instance of javax.faces.model.SelectItem. Type found: java.util.ArrayList.


What the hell..


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 30, 2008 10:17 am 
Senior
Senior

Joined: Tue May 10, 2005 9:00 am
Posts: 125
You original problem is that you store #{m.id} inside your Set instead of #{m}. That is you store Integer where hibernate expect to see a Role. Your other erros (about SelectItem) comes from your changes trying to fix your first problem. Just fix your first problem (use #{m} instead of #{m.id} ) and cancel your other changes :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 30, 2008 10:46 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
I have tried it with:

Code:
<s:selectItems value="#{bean.rolesList}" var="m" label="#{m.description}"/>


Code:
<s:selectItems value="#{bean.rolesList}" var="m" label="#{m} itemValue="#{m}"/>


and so on..the same failure occurs..

now, I go to sleep and try it in few hours..I let u know bout my progress..


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 30, 2008 2:35 pm 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
okay,

I have a really strange behaviour:

I found out that the failure depends on my Collection-Type.

At first, I have printed out my result types from selectmanycheckbox:

Code:
20:23:36,484 INFO  [STDOUT] Element in set: entity.Role@f86dd86c: java.lang.String
20:23:36,484 INFO  [STDOUT] Element in set: entity.Role@a57fe861: java.lang.String


Look at my entity "Person":

Code:
//    private Set<Role> roles = new HashSet<Role>();
    private List<Role> roles = new ArrayList<Role>();
//      private Collection<Role> roles ;


When I use List, then the following stacktrace occurs:

Code:
Caused by: org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of entity.Role.idRole
   at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:171)
   at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:183)
   at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3591)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:98)
   at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:687)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:669)
   at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:245)
   at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
   at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
   at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
   at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
   at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
   at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
   at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
   at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
   at org.hibernate.event.def.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:407)
   at org.hibernate.event.def.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:152)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:126)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
   at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
   at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:227)
   ... 139 more
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:145)
   ... 161 more



But when I use

instead of

Code:
private List<Role> roles = new ArrayList<Role>();


this:

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


or that:

Code:
private Collection<Role> roles ;


then NO error occurs, NO persisting occurs, no stacktrace occurs.
I get NO feedback (in my console), when I use Collection or Set instead of List. I press the button "save" and the server tells me NOTHING, what is happend. That really sucks! (I use up-to-date jBOSS 4.2.x, hibernate 3.2.x)

I do not know, where the problem lies. It is an hibernate issue!

(Besides, having a ManyToMany-Relation, u should only use Set or List as they contain no duplicate elements)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 01, 2008 2:52 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
In http://hibernate.bluemars.net/272.780.html

there is maybe an help for me..but I do not have any valueOf in my Person-Class...


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 01, 2008 7:33 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
I tried that, without success..the same failure is still existing..I red the hibernate docu s.21..and adapted the example for JPA..however for me, it does not work!

Should I implement an converter to gather the value from a selectmanyCheckbox only to insert it in an Set?!..that s very comfortable..


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 01, 2008 11:00 am 
Regular
Regular

Joined: Tue Jun 03, 2008 1:12 pm
Posts: 84
Location: germany
ohh..I guess, I got it...I am using a SEQUENCE-Generator for generating ID's for PERSON-Objects..when I persist a new Person-Object, I have no ID before, so I must do two transactions to persist a Person-Object.

So I have to create a method in my entityBean Person:

Code:
..
@Transient
public void addROLE_PERSON(idRole, idPerson) {
...
}


Refering to Hibernate-Docu (page 21)..."This is called automatic dirty checking"..does not work for me..or do I do anything false???


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