Mapping a collection of entities...

6 Messages Forum Options Options
Embed this topic
Permalink
cobbra
Mapping a collection of entities...
Reply Threaded MoreMore options
Print post
Permalink
Hello all,

I'm trying to teach myself OpenJPA and failing miserably...  I have two entities (code below) where one contains a collection of the other.  The intent is for UserInfo to be able to contain a collection (or List) of an arbitrary number of UserProperties.  The UserProperties are defined at run-time by data entered through the application.

With it defined as follows in the ear file deploys fine in Geronimo, but calling any of the service methods that try to query or insert data result in the following errors:
javax.ejb.EJBException: The bean encountered a non-application exception.; nested exception is:
        <openjpa-1.0.2-r420667:627158 fatal user error> org.apache.openjpa.persistence.ArgumentException: You have supplied columns for "com.whitetail.sawhorse.data.UserInfo.userProperties", but this mapping cannot have columns in this context.

The relevant portion of the entities are defined as:
@Entity
@Table(name="userinfo")
public class UserInfo implements Serializable {

        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @Column(name="id", nullable=false, insertable=false, updatable=false)
        private Integer id;
       
        @OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
        @JoinColumn(name="prop_id", referencedColumnName="userId")
        private Collection<UserProperties> userProperties;
       
and

@Entity
@Table(name="userproperties")
public class UserProperties implements Serializable {

        @Id
        @Column(name="id", nullable=false)
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        private Integer id;
       
        @OneToOne(fetch=FetchType.LAZY)
        @JoinColumn(name="user_id", referencedColumnName="id")
        private UserInfo userInfo;
       
I thought I had it right according to the documentation and the few examples I've seen, but I've got something wrong.  Any help getting this solved would be greatly appreciated.

Cheers!
Randy
Wes Wannemacher
Re: Mapping a collection of entities...
Reply Threaded MoreMore options
Print post
Permalink

On Tue, 2008-11-18 at 19:36 -0600, cobbra@... wrote:
> Hello all,
>
> I'm trying to teach myself OpenJPA and failing miserably...  
> I have two entities (code below) where one contains a collection
> of the other.  The intent is for UserInfo to be able to contain
> a collection (or List) of an arbitrary number of UserProperties.  
> The UserProperties are defined at run-time by data entered through
> the application.
>

I'm a bit of a newb myself, but I think you need to change your
UserProperties like below -



@Entity
@Table(name="userproperties")
public class UserProperties implements Serializable {

        @Id
        @Column(name="id", nullable=false)
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        private Integer id;
       
        @ManyToOne(mappedBy="UserInfo", fetch=FetchType.LAZY)
        @JoinColumn(name="user_id", referencedColumnName="id")
        private UserInfo userInfo;

cobbra
Re: Mapping a collection of entities...
Reply Threaded MoreMore options
Print post
Permalink
Thanks for the quick reply.  I'll give that a shot.

---- Wes Wannemacher <wesw@...> wrote:

>
> On Tue, 2008-11-18 at 19:36 -0600, cobbra@... wrote:
> > Hello all,
> >
> > I'm trying to teach myself OpenJPA and failing miserably...  
> > I have two entities (code below) where one contains a collection
> > of the other.  The intent is for UserInfo to be able to contain
> > a collection (or List) of an arbitrary number of UserProperties.  
> > The UserProperties are defined at run-time by data entered through
> > the application.
> >
>
> I'm a bit of a newb myself, but I think you need to change your
> UserProperties like below -
>
>
>
> @Entity
> @Table(name="userproperties")
> public class UserProperties implements Serializable {
>
> @Id
> @Column(name="id", nullable=false)
> @GeneratedValue(strategy=GenerationType.IDENTITY)
> private Integer id;
>
> @ManyToOne(mappedBy="UserInfo", fetch=FetchType.LAZY)
> @JoinColumn(name="user_id", referencedColumnName="id")
> private UserInfo userInfo;
>
cobbra
Re: Mapping a collection of entities...
Reply Threaded MoreMore options
Print post
Permalink
Same result.

I'm running in Geronimo 2.1.3 which IIRC comes with OpenJPA 1.0.2.  As such, I couldn't use the syntax you suggested, so I used the one that compiles.  The javax.persistence library with 1.0.2 says "mappedBy" wasn't found... so I used this syntax in UserProperties:

        @ManyToOne(targetEntity=UserInfo.class, fetch=FetchType.LAZY)
        @JoinColumn(name="user_id", referencedColumnName="id")
        private UserInfo userInfo;

Basically, the only change was changing "mappedBy" to "targetEntity".  And, I've tried this same change to both UserProperties and UserInfo with the same results I was getting originally.

Thanks,
Randy

---- cobbra@... wrote:

> Thanks for the quick reply.  I'll give that a shot.
>
> ---- Wes Wannemacher <wesw@...> wrote:
> >
> > On Tue, 2008-11-18 at 19:36 -0600, cobbra@... wrote:
> > > Hello all,
> > >
> > > I'm trying to teach myself OpenJPA and failing miserably...  
> > > I have two entities (code below) where one contains a collection
> > > of the other.  The intent is for UserInfo to be able to contain
> > > a collection (or List) of an arbitrary number of UserProperties.  
> > > The UserProperties are defined at run-time by data entered through
> > > the application.
> > >
> >
> > I'm a bit of a newb myself, but I think you need to change your
> > UserProperties like below -
> >
> >
> >
> > @Entity
> > @Table(name="userproperties")
> > public class UserProperties implements Serializable {
> >
> > @Id
> > @Column(name="id", nullable=false)
> > @GeneratedValue(strategy=GenerationType.IDENTITY)
> > private Integer id;
> >
> > @ManyToOne(mappedBy="UserInfo", fetch=FetchType.LAZY)
> > @JoinColumn(name="user_id", referencedColumnName="id")
> > private UserInfo userInfo;
> >
Wes Wannemacher
Re: Mapping a collection of entities...
Reply Threaded MoreMore options
Print post
Permalink
My understanding is that you choose one of the two sides as "owning" the
relationship. Let's assume that we want the @ManyToOne side as the
owner. In that case, you'll map the @ManyToOne as follows -

  @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
  private UserInfo userInfo;

And then, we'll map the other side of the relationship as follows -

 @OneToMany(mappedBy="publisher", cascade=CascadeType.PERSIST)
 private Collection<UserProperties> userProperties;


Notice that the @JoinColumns were removed because I think OpenJPA will
figure out on it's own to join by the @Id columns. IIUC, the syntax
above should create a bi-directional relationship in the database
between the two entities.

-Wes




On Tue, 2008-11-18 at 20:25 -0600, cobbra@... wrote:

> Same result.
>
> I'm running in Geronimo 2.1.3 which IIRC comes with OpenJPA 1.0.2.  As such, I couldn't use the syntax you suggested, so I used the one that compiles.  The javax.persistence library with 1.0.2 says "mappedBy" wasn't found... so I used this syntax in UserProperties:
>
> @ManyToOne(targetEntity=UserInfo.class, fetch=FetchType.LAZY)
> @JoinColumn(name="user_id", referencedColumnName="id")
> private UserInfo userInfo;
>
> Basically, the only change was changing "mappedBy" to "targetEntity".  And, I've tried this same change to both UserProperties and UserInfo with the same results I was getting originally.
>
> Thanks,
> Randy
>
> ---- cobbra@... wrote:
> > Thanks for the quick reply.  I'll give that a shot.
> >
> > ---- Wes Wannemacher <wesw@...> wrote:
> > >
> > > On Tue, 2008-11-18 at 19:36 -0600, cobbra@... wrote:
> > > > Hello all,
> > > >
> > > > I'm trying to teach myself OpenJPA and failing miserably...  
> > > > I have two entities (code below) where one contains a collection
> > > > of the other.  The intent is for UserInfo to be able to contain
> > > > a collection (or List) of an arbitrary number of UserProperties.  
> > > > The UserProperties are defined at run-time by data entered through
> > > > the application.
> > > >
> > >
> > > I'm a bit of a newb myself, but I think you need to change your
> > > UserProperties like below -
> > >
> > >
> > >
> > > @Entity
> > > @Table(name="userproperties")
> > > public class UserProperties implements Serializable {
> > >
> > > @Id
> > > @Column(name="id", nullable=false)
> > > @GeneratedValue(strategy=GenerationType.IDENTITY)
> > > private Integer id;
> > >
> > > @ManyToOne(mappedBy="UserInfo", fetch=FetchType.LAZY)
> > > @JoinColumn(name="user_id", referencedColumnName="id")
> > > private UserInfo userInfo;
> > >

cobbra
Re: Mapping a collection of entities...
Reply Threaded MoreMore options
Print post
Permalink
Perfect!  Many thanks.  Setting UserProperties as the owner and removing the @JoinColumn from both entities did the trick!

Looks like I need more study, or just more patience while I "try" to get things right.

Thank you!
Randy

---- Wes Wannemacher <wesw@...> wrote:

> My understanding is that you choose one of the two sides as "owning" the
> relationship. Let's assume that we want the @ManyToOne side as the
> owner. In that case, you'll map the @ManyToOne as follows -
>
>   @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
>   private UserInfo userInfo;
>
> And then, we'll map the other side of the relationship as follows -
>
>  @OneToMany(mappedBy="publisher", cascade=CascadeType.PERSIST)
>  private Collection<UserProperties> userProperties;
>
>
> Notice that the @JoinColumns were removed because I think OpenJPA will
> figure out on it's own to join by the @Id columns. IIUC, the syntax
> above should create a bi-directional relationship in the database
> between the two entities.
>
> -Wes
>
>
>
>
> On Tue, 2008-11-18 at 20:25 -0600, cobbra@... wrote:
> > Same result.
> >
> > I'm running in Geronimo 2.1.3 which IIRC comes with OpenJPA 1.0.2.  As such, I couldn't use the syntax you suggested, so I used the one that compiles.  The javax.persistence library with 1.0.2 says "mappedBy" wasn't found... so I used this syntax in UserProperties:
> >
> > @ManyToOne(targetEntity=UserInfo.class, fetch=FetchType.LAZY)
> > @JoinColumn(name="user_id", referencedColumnName="id")
> > private UserInfo userInfo;
> >
> > Basically, the only change was changing "mappedBy" to "targetEntity".  And, I've tried this same change to both UserProperties and UserInfo with the same results I was getting originally.
> >
> > Thanks,
> > Randy
> >
> > ---- cobbra@... wrote:
> > > Thanks for the quick reply.  I'll give that a shot.
> > >
> > > ---- Wes Wannemacher <wesw@...> wrote:
> > > >
> > > > On Tue, 2008-11-18 at 19:36 -0600, cobbra@... wrote:
> > > > > Hello all,
> > > > >
> > > > > I'm trying to teach myself OpenJPA and failing miserably...  
> > > > > I have two entities (code below) where one contains a collection
> > > > > of the other.  The intent is for UserInfo to be able to contain
> > > > > a collection (or List) of an arbitrary number of UserProperties.  
> > > > > The UserProperties are defined at run-time by data entered through
> > > > > the application.
> > > > >
> > > >
> > > > I'm a bit of a newb myself, but I think you need to change your
> > > > UserProperties like below -
> > > >
> > > >
> > > >
> > > > @Entity
> > > > @Table(name="userproperties")
> > > > public class UserProperties implements Serializable {
> > > >
> > > > @Id
> > > > @Column(name="id", nullable=false)
> > > > @GeneratedValue(strategy=GenerationType.IDENTITY)
> > > > private Integer id;
> > > >
> > > > @ManyToOne(mappedBy="UserInfo", fetch=FetchType.LAZY)
> > > > @JoinColumn(name="user_id", referencedColumnName="id")
> > > > private UserInfo userInfo;
> > > >
>