I have an entity using access type
property. Within that entity, I have a List which I want to access with field access, but expose via a public getter returning an array instead of a list. I have added an @AccessType("field") annotation to the getter method. Hibernate annotations appear to be using the reflected type from the getter method, rather than the type of the field when building its meta-data.
Hibernate Version: hibernate-3.2.0CR1 and hibernate-annotations-3.2.0CR1
Mapping documents:
Code:
package com.sandstone_tech.framework.persistence.test;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Version;
@Entity
@Table(name="Pet")
public class Pet
{
private Long id;
private Long objectVersion;
private PetOwner owner;
private String name;
@ManyToOne(cascade = CascadeType.PERSIST)
public PetOwner getOwner()
{
return owner;
}
public void setOwner(PetOwner owner)
{
this.owner = owner;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@Id @GeneratedValue
public Long getId()
{
return id;
}
public void setId(Long l)
{
id = l;
}
@Version
public Long getObjectVersion()
{
return objectVersion;
}
public void setObjectVersion(Long version2)
{
this.objectVersion = version2;
}
}
package com.sandstone_tech.framework.persistence.test;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Version;
import org.hibernate.annotations.AccessType;
import org.hibernate.annotations.IndexColumn;
/**
* Test class for testing persistence framework
*
* @author andrewduckworth
*
*/
@Entity
public class PetOwner
{
private Long id;
private Long objectVersion;
private String name;
private List<Pet> pets = new ArrayList<Pet>();
@OneToMany(targetEntity=Pet.class, cascade=CascadeType.ALL)
@IndexColumn(name="ownerOrder")
@JoinColumn(name="ownerId")
@AccessType("field")
public Pet[] getPets()
{
return pets.toArray(new Pet[]{});
}
public void addPet(Pet pet)
{
pets.add(pet);
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@Id @GeneratedValue
public Long getId()
{
return id;
}
public void setId(Long l)
{
id = l;
}
@Version
public Long getObjectVersion()
{
return objectVersion;
}
public void setObjectVersion(Long version2)
{
this.objectVersion = version2;
}
}
Code between sessionFactory.openSession() and session.close():
AnnotationConfiguration config = new AnnotationConfiguration();
config.setProperties(getProperties());
config.addAnnotatedClass(PetOwner.class);
config.addAnnotatedClass(Pet.class);
SessionFactory f = config.buildSessionFactory();
Session s = f.openSession();
PetOwner owner = new PetOwner();
owner.setName("Fred");
Pet cat = new Pet();
cat.setName("keats");
cat.setOwner(owner);
owner.addPet(cat);
Pet dog = new Pet();
dog.setName("fido");
dog.setOwner(owner);
owner.addPet(dog);
s.persist(owner);
s.flush();
s.close();
Long id = owner.getId();
// Now try and reload it in a different session
// and check they have been persisted correctly
s = f.openSession();
Object o = s.get(PetOwner.class, id);
assertTrue(o instanceof PetOwner);
PetOwner p2 = (PetOwner) o;
assertTrue(p2.getPets().length == 2);
s.close();
Full stack trace of any exception that occurs:
Quote:
java.lang.ClassCastException: java.util.ArrayList
at org.hibernate.type.ArrayType.getElementsIterator(ArrayType.java:48)
at org.hibernate.type.CollectionType.getElementsIterator(CollectionType.java:188)
at org.hibernate.engine.CascadingAction.getAllElementsIterator(CascadingAction.java:266)
at org.hibernate.engine.CascadingAction.access$100(CascadingAction.java:21)
at org.hibernate.engine.CascadingAction$8.getCascadableChildrenIterator(CascadingAction.java:206)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:288)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:185)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:160)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
at org.hibernate.engine.Cascade.cascade(Cascade.java:248)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:437)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:326)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:180)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:108)
at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:131)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:87)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:38)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:620)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:594)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:598)
at com.sandstone_tech.framework.persistence.test.PersistenceTest.testFieldAccessMappingOnGetter(PersistenceTest.java:439)
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 junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Name and version of the database you are using:
SQLServer
The generated SQL (show_sql=true):
Debug level Hibernate log excerpt:
Problems with Session and transaction handling?
Read this:
http://hibernate.org/42.html