openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Goodenough <david.goodeno...@btconnect.com>
Subject Re: Please make Exceptions more useful...
Date Thu, 03 Apr 2008 13:42:59 GMT
On Thursday 03 April 2008, David Goodenough wrote:
> On Wednesday 02 April 2008, David Goodenough wrote:
> > On Wednesday 02 April 2008, Patrick Linskey wrote:
> > > Hi,
> > >
> > > Can you post the full stack trace?
> > >
> > > -Patrick
> > >
> > > On Wed, Apr 2, 2008 at 7:59 AM, David Goodenough
> > >
> > > <david.goodenough@btconnect.com> wrote:
> > > > On Wednesday 02 April 2008, David Goodenough wrote:
> > > >  > I just got an error message which said:-
> > > >  >
> > > >  > Exception in thread "main" <openjpa-1.0.2-r420667:627158 nonfatal
> > > >  > general error>
> > > >  > org.apache.openjpa.persistence.PersistenceException:
> > > >  > java.util.Date cannot be cast to java.util.Collection
> > > >  >
> > > >  > In this (and the accompanying stack trace) there is no indication
> > > >  > which Date object cannot be cast to a Collection.  Yes from the
> > > >  > stack trace I know that I was trying to persist a particular root
> > > >  > object, but I have no idea which class and field this error refers
> > > >  > to.  Simply adding the class and field would make debugging so
> > > >  > much easier.
> > > >  >
> > > >  > Then once I know which Date field it might be, I can start to try
> > > >  > to work out why it wanted to cast it to a collection.  Presumably
> > > >  > this was it was trying to map this to a particular table, or to
a
> > > >  > set of objects of a given type, and again it would be useful to
> > > >  > know what application object as opposed to raw java class it was
> > > >  > trying to map to.
> > > >  >
> > > >  > David
> > > >
> > > >  Well I dug a little further into this one, and I am confused.  It
> > > > does indeed have a Date object that is it trying to cast as a
> > > > Collection.
> > > >
> > > >  From the FieldMapping object current at the time when it fails the
> > > > field in question is uk.co.dga.bm.jpa.Role.roles, and its definition
> > > > is:-
> > > >
> > > >         @OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
> > > > private List<Role> roles;
> > > >
> > > >  Which is (quite properly) a Collection, and is not a date (yes I
> > > > know, I should not be using CascadeType.ALL, but at least here is
> > > > does include PERSIST.  As it happens this list is empty.
> > > >
> > > >  There is a Date, but it is in a superclass, its my @Version.  The
> > > > superclass is declared:-
> > > >
> > > >  @MappedSuperclass public class Basic extends Observed {
> > > >         @Version @Temporal(TemporalType.TIMESTAMP) private Date
> > > > version;
> > > >
> > > >  and there is the version field as well.  The outer class is
> > > > declared:-
> > > >
> > > >  @Entity @Table(name="Roles") public class Role extends Basic {
> > > >
> > > >  All of which looks right to my untrained eye.  My guess is that for
> > > > some reason the system is getting confused about which class it is
> > > > looking at, the outer one or the super class but I do not know.  I
> > > > have tried clearing the binaries out from the Eclipse project, and
> > > > rebuilding everything, but that did not help.
> > > >
> > > >  Is this a known problem (in which case is there a workaround), if
> > > > not what do you need to help track it down.
> > > >
> > > >  David
> >
> > Exception in thread "main" <openjpa-1.0.2-r420667:627158 nonfatal general
> > error> org.apache.openjpa.persistence.PersistenceException:
> > java.util.Date cannot be cast to java.util.Collection
> >         at
> > org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2411) at
> > org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2225) at
> > org.apache.openjpa.kernel.DelegatingBroker.persist(DelegatingBroker.java:
> >10 05) at
> > org.apache.openjpa.persistence.EntityManagerImpl.persist(EntityManagerImp
> >l. java:541) at uk.co.dga.bm.loader.CreateUser.run(CreateUser.java:55) at
> > uk.co.dga.bm.loader.CreateUser.main(CreateUser.java:67) Caused by:
> > java.lang.ClassCastException: java.util.Date cannot be cast to
> > java.util.Collection
> >         at
> > org.apache.openjpa.kernel.SingleFieldManager.persist(SingleFieldManager.j
> >av a:267) at
> > org.apache.openjpa.kernel.StateManagerImpl.cascadePersist(StateManagerImp
> >l. java:2859) at
> > org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2406) ... 5
> > more
> >
> > David
>
> I have been re-reading the manual, in particular the bits about
> MappedSuperclass and Embeddable.  And I am confused, and maybe this
> is why I am hitting this problem.
>
> I have this Role class which has the following fields:-
>
> @Entity @Table(name="Roles") public class Role extends Basic {
> 	@Id private String id;
> 	private String fullName;
> 	@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL) private
> List<Role> roles;
>
> There are no other fields, just a bunch of methods (largely getters and
> setters).
>
> Basic is defined as:-
>
> @MappedSuperclass public class Basic extends Observed {
> 	@Version @Temporal(TemporalType.TIMESTAMP) private Date version;
> 	@ManyToOne(fetch=FetchType.LAZY,cascade=CascadeType.ALL) private Role
> updater;
> 	@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL) private
> List<Access>accesses = new ArrayList<Access>();
>
> It has a couple of static fields which obviously to not take part in
> persistence, and the usual collection of methods.
>
> and Observed (which I need for beansbinding) as:-
>
> @MappedSuperclass public class Observed {
> 	transient protected PropertyChangeSupport propertyChangeSupport;
> 	{
> 		propertyChangeSupport = new PropertyChangeSupport(this);
> 	}
> }
>
> Now nothing in Observed needs to be mapped as its only field is transient,
> but I still seem to have to mark it as MappedSuperclass to keep the
> enhancer quiet.
>
> Looking at the error, it looks as though the persistence logic is getting
> confused as to which class it is looking at.  When trying to persist
> Basic.version it is looking at the definition of Role.roles, which matches
> with the report that it is trying (and failing) to map a Date to a
> Collection.
>
> I am doing all my definitions with annotation in the java source, rather
> than trying to use orm.xml which is empty - I prefer to keep things in one
> place, I find it easier to keep things consistant that way). 
> persistence.xml only lists the classes, and defines the JDBC properties and
> controls the log level and the SynchronizeMappings setting.
>
> I am new to this world of JPA, and so it is more that likely that I am
> marking the classes/fields wrongly.  Can anyone point me in the right
> direction?
>
> David

Well I have done some more experiments.

Removing Basic as a superclass to Role (and replacing it with Observed)
stops the problem.

If I include Basic then I have to remove all its fields in order to make it
work again.  Which rather defeats the point.

I really do not want to have to repeat the function of Basic in each class,
and apart from noticing that the manual says that the super class is
"normally abstract" I can not see why it does not do what I need.  I have
been reading around the web and there are examples of using real
classes as @MappedSuperclass, and it does say "normally" with nothing
to say what if anything has to be done differently if they are not abstract.

David

Mime
View raw message