You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Ognjen Blagojevic <og...@etf.bg.ac.yu> on 2008/04/03 13:19:30 UTC

How to PERSIST object without loading references?

Hi all,

Is there a way to persist an Entity without loading all the referenced 
objects?

I know that this is possible:

Employee e = new Employe();
e.setName("John Doe");
e.setIdDepartment(findDepartmentByPrimaryKey(idDept));
e.setIdRank(findRankByPrimaryKey(idRank));
// and so on
em.persist(e);

But if I have a lot of references, and lot of INSERTS to do, this 
becames import with poor performace (before each INSERT statemet app 
must execute N selects).

It would be much faster if I can set references without looking them up:

Employee e = new Employe();
e.setName("John Doe");
Department dept = new Department();
dept.setIdDepartment(idDept);
e.setIdDepartment(dept);
// and so on
em.persist(e);

(Please note here: I'm not trying to insert new department, but rather 
to set a reference to existing one without looking it up in the database.)

But this seems impossible. Without CascadeType.PERSIST it throws 
something like:

<openjpa-1.0.2-r420667:627158 nonfatal user error> 
org.apache.openjpa.persistence.InvalidStateException: Encountered 
unmanaged object "mypackage.Department@18952cc" in persistent field 
"mypackage.Employee.idDepartment" of managed object 
"mypackage.Employee-5" during flush.  However, this field does not allow 
to be CascadeType.PERSIST.  You cannot flush unmanaged objects.

Ok, I add the CascadeType.PERSIST, and then:

org.apache.openjpa.persistence.InvalidStateException: The generated 
value processing detected an existing value assigned to this field: 
mypackage.Department.idDepartment.  This existing value was either 
provided via an initializer or by calling the setter method.  You either 
need to remove the @GeneratedValue annotation or modify the code to 
remove the initializer processing.


It must be a way to INSERT objects in the database without looking up 
for all the references, but I am not able to find it.

Regards,
Ognjen

Re: How to PERSIST object without loading references?

Posted by Fay Wang <fy...@yahoo.com>.
Hi Enrico,
   Here is my example, and it runs fine:

(1) EntityA.java:

@Entity
public class EntityA  {
    @Column(name="A_ID")
	@Id private int id;
    
    private String name;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumns({@JoinColumn(name="B_ID",
                  referencedColumnName="B_ID",
                  insertable=false,updatable=false)})
    private EntityB entityB;    

    ... omit getters and setters
}

(2) EntityB:
@Entity
public class EntityB  {
    @Column(name="B_ID")
    @Id private int id;
	
    private String name; 

 ... omit getters and setters

}

(3) the test case:
	em.getTransaction().begin();
	EntityA a = new EntityA();
	a.setName("1");
	a.setId(1);
	em.persist(a);
	em.getTransaction().commit();


Do you want to try my test case to see if it works?

-f


--- On Wed, 6/11/08, Enrico Goosen <eg...@metropolitan.co.za> wrote:

> From: Enrico Goosen <eg...@metropolitan.co.za>
> Subject: Re: How to PERSIST object without loading references?
> To: users@openjpa.apache.org
> Date: Wednesday, June 11, 2008, 11:44 AM
> I'm getting so frustrated with OpenJPA!
> I'm also experiencing the problem listed in previous
> reply, and once again,
> no response to that post.
> Here's some code to explain my problem:
> TblPdtbnf.java:
> @OneToOne(fetch = FetchType.LAZY)
> @JoinColumns({@JoinColumn(name
> ="PDTBNF_ID",referencedColumnName="PDTBNF_ID",insertable=false,updatable=false)})
> 
> private TblPdtbnfcde tblPdtbnfcde;
> 
> When I save a TblPdtbnf record, I get this error:
> ERRORJun 11 20:30:12 Encountered new object
> "za.co.metcapri.model.ebstatus.TblPdtbnfcde@114b3af"
> in persistent field
> "za.co.metcapri.model.ebstatus.TblPdtbnf.tblPdtbnfcde"
> of managed object
> "za.co.metcapri.model.ebstatus.TblPdtbnf@87c7a8"
> during attach.  However,
> this field does not allow cascade attach.  You cannot
> attach a reference to
> a new object without cascading.;
> 
> But I don't want to save the tblPdtbnfcde...didn't
> I make that clear by
> adding insertable=false!!!
> 
> If I remove insertable=false, updatable=false...that
> doesn't help either.
> 
> Do I have to set that field to null to save this record?
> There must be a better way. 
> 
> Is there anybody out there that knows the solution???
> 
> 
> Anonimus wrote:
> > 
> > 
> > Ognjen Blagojevic wrote:
> >> 
> >> It must be a way to INSERT objects in the database
> without looking up 
> >> for all the references, but I am not able to find
> it.
> >> 
> > 
> > My problem is similar as yours, with a single
> difference.
> > I don't mind loading all the references because I
> need them in the
> > program. But I don't know how to insert object and
> disable an attempt of
> > inserting in related tables. If I put cascade =
> cascadeType.PERSIST, I get
> > an exception (as you do). If I don't put cascade =
> cascadeType.PERSIST
> > (which is logical), I get an exception. Since I'm
> new in JPA, I'm quite
> > lost now.
> > 
> > 
> 
> -- 
> View this message in context:
> http://www.nabble.com/How-to-PERSIST-object-without-loading-references--tp16472647p17784459.html
> Sent from the OpenJPA Users mailing list archive at
> Nabble.com.


      

Re: How to PERSIST object without loading references?

Posted by Enrico Goosen <eg...@metropolitan.co.za>.
I'm getting so frustrated with OpenJPA!
I'm also experiencing the problem listed in previous reply, and once again,
no response to that post.
Here's some code to explain my problem:
TblPdtbnf.java:
@OneToOne(fetch = FetchType.LAZY)
@JoinColumns({@JoinColumn(name
="PDTBNF_ID",referencedColumnName="PDTBNF_ID",insertable=false,updatable=false)}) 
private TblPdtbnfcde tblPdtbnfcde;

When I save a TblPdtbnf record, I get this error:
ERRORJun 11 20:30:12 Encountered new object
"za.co.metcapri.model.ebstatus.TblPdtbnfcde@114b3af" in persistent field
"za.co.metcapri.model.ebstatus.TblPdtbnf.tblPdtbnfcde" of managed object
"za.co.metcapri.model.ebstatus.TblPdtbnf@87c7a8" during attach.  However,
this field does not allow cascade attach.  You cannot attach a reference to
a new object without cascading.;

But I don't want to save the tblPdtbnfcde...didn't I make that clear by
adding insertable=false!!!

If I remove insertable=false, updatable=false...that doesn't help either.

Do I have to set that field to null to save this record?
There must be a better way. 

Is there anybody out there that knows the solution???


Anonimus wrote:
> 
> 
> Ognjen Blagojevic wrote:
>> 
>> It must be a way to INSERT objects in the database without looking up 
>> for all the references, but I am not able to find it.
>> 
> 
> My problem is similar as yours, with a single difference.
> I don't mind loading all the references because I need them in the
> program. But I don't know how to insert object and disable an attempt of
> inserting in related tables. If I put cascade = cascadeType.PERSIST, I get
> an exception (as you do). If I don't put cascade = cascadeType.PERSIST
> (which is logical), I get an exception. Since I'm new in JPA, I'm quite
> lost now.
> 
> 

-- 
View this message in context: http://www.nabble.com/How-to-PERSIST-object-without-loading-references--tp16472647p17784459.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: How to PERSIST object without loading references?

Posted by Anonimus <sa...@gmail.com>.
I've solved my problem by replaceing 

em.persist(e);

with

e = (Employee) em.merge(e);

It works now.
-- 
View this message in context: http://www.nabble.com/How-to-PERSIST-object-without-loading-references--tp16472647p17803850.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: How to PERSIST object without loading references?

Posted by Anonimus <sa...@gmail.com>.
Hi Michael,

your assumptions are correct. 


After em.persist(e); I get this exception if I specify CascadeType.PERSIST:

>org.apache.openjpa.persistence.InvalidStateException: The generated value
> processing detected an existing value assigned to this field:
> mypackage.Department.idDepartment.  This existing value was either
> provided
> via an initializer or by calling the setter method.  You either need to
> remove the @GeneratedValue annotation or modify the code to remove the
> initializer processing. 

because id in referenced object has an annotation
@GeneratedValue(strategy=GenerationType.IDENTITY)  and that is something I
cannot and don't want to change.

If I don't specify CascadeType.PERSIST, I get this error:

> <openjpa-1.0.2-r420667:627158 nonfatal user error>
> org.apache.openjpa.persistence.InvalidStateException: Encountered
> unmanaged object "mypackage.Department@18952cc" in persistent field
> "mypackage.Employee.idDepartment" of managed object
> "mypackage.Employee-5" during flush.  However, this field does not allow
> to be CascadeType.PERSIST.  You cannot flush unmanaged objects. 


Michael Dick wrote:
> 
> Hi Anonimus,
> 
> What exception do you get when you don't specify CascadeType.PERSIST?
> 
> I'm assuming you're doing something like this :
> 
> Employee e = new Employe();
> e.setName("John Doe");
> 
> Department d = em.find(Department.class, idDept);  // this is what I think
> you mean by loading all the references.
> e.setIdDepartment(d);
> 
> Rank r = em.find(Rank.class, idRank);
> e.setIdRank(r);
> 
> // and so on
> 
> em.persist(e);
> 
> If that's the case then you shouldn't get any exceptions.
> 
> Thanks,
> 
> -Mike
> 
> On Wed, Jun 11, 2008 at 8:52 AM, Anonimus <sa...@gmail.com> wrote:
> 
>>
>>
>> Ognjen Blagojevic wrote:
>> >
>> > It must be a way to INSERT objects in the database without looking up
>> > for all the references, but I am not able to find it.
>> >
>>
>> My problem is similar as yours, with a single difference.
>> I don't mind loading all the references because I need them in the
>> program.
>> But I don't know how to insert object and disable an attempt of inserting
>> in
>> related tables. If I put cascade = cascadeType.PERSIST, I get an
>> exception
>> (as you do). If I don't put cascade = cascadeType.PERSIST (which is
>> logical), I get an exception. Since I'm new in JPA, I'm quite lost now.
>>
>> --
>> View this message in context:
>> http://www.nabble.com/How-to-PERSIST-object-without-loading-references--tp16472647p17778155.html
>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>
>>
> 
> 

-- 
View this message in context: http://www.nabble.com/How-to-PERSIST-object-without-loading-references--tp16472647p17787968.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: How to PERSIST object without loading references?

Posted by Michael Dick <mi...@gmail.com>.
Hi Anonimus,

What exception do you get when you don't specify CascadeType.PERSIST?

I'm assuming you're doing something like this :

Employee e = new Employe();
e.setName("John Doe");

Department d = em.find(Department.class, idDept);  // this is what I think
you mean by loading all the references.
e.setIdDepartment(d);

Rank r = em.find(Rank.class, idRank);
e.setIdRank(r);

// and so on

em.persist(e);

If that's the case then you shouldn't get any exceptions.

Thanks,

-Mike

On Wed, Jun 11, 2008 at 8:52 AM, Anonimus <sa...@gmail.com> wrote:

>
>
> Ognjen Blagojevic wrote:
> >
> > It must be a way to INSERT objects in the database without looking up
> > for all the references, but I am not able to find it.
> >
>
> My problem is similar as yours, with a single difference.
> I don't mind loading all the references because I need them in the program.
> But I don't know how to insert object and disable an attempt of inserting
> in
> related tables. If I put cascade = cascadeType.PERSIST, I get an exception
> (as you do). If I don't put cascade = cascadeType.PERSIST (which is
> logical), I get an exception. Since I'm new in JPA, I'm quite lost now.
>
> --
> View this message in context:
> http://www.nabble.com/How-to-PERSIST-object-without-loading-references--tp16472647p17778155.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>
>

Re: How to PERSIST object without loading references?

Posted by Anonimus <sa...@gmail.com>.

Ognjen Blagojevic wrote:
> 
> It must be a way to INSERT objects in the database without looking up 
> for all the references, but I am not able to find it.
> 

My problem is similar as yours, with a single difference.
I don't mind loading all the references because I need them in the program.
But I don't know how to insert object and disable an attempt of inserting in
related tables. If I put cascade = cascadeType.PERSIST, I get an exception
(as you do). If I don't put cascade = cascadeType.PERSIST (which is
logical), I get an exception. Since I'm new in JPA, I'm quite lost now.

-- 
View this message in context: http://www.nabble.com/How-to-PERSIST-object-without-loading-references--tp16472647p17778155.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: How to PERSIST object without loading references?

Posted by "Edmond M." <ed...@uclouvain.be>.


Ognjen Blagojevic wrote:
> 
> Edmond M. wrote:
> ...
>> I've been facing the same kind of problem ; my program keeps complaining
>> about "unmanaged object" despite using EntityManager.getReference() as
>> suggested by Patrick. I wonder what I've been doing wrong. Would you show
>> the piece of code (and possibly the related configuration part in
>> orm.xml)
>> that made your program run ?
> 
> This is really an old thread. :)
> 
> Something like:
> 
>      em.getTransaction().begin();
>      Child c = new Child();
>      c.setName("Bob");
>      c.setParent(em.getReference(Parent.class, 123););
>      em.persist(predmet);
>      em.getTransaction().commit();
> 
> should work. More or less, thats what I'm doing. Maybe you could post 
> your code, and exact stack trace?
> 
> Regards,
> Ognjen
> 
> 

Your example helps; thank your very much.

regards !

Edmond/

-- 
View this message in context: http://n2.nabble.com/How-to-PERSIST-object-without-loading-references--tp210631p735807.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: How to PERSIST object without loading references?

Posted by Ognjen Blagojevic <og...@etf.bg.ac.yu>.
Edmond M. wrote:
...
> I've been facing the same kind of problem ; my program keeps complaining
> about "unmanaged object" despite using EntityManager.getReference() as
> suggested by Patrick. I wonder what I've been doing wrong. Would you show
> the piece of code (and possibly the related configuration part in orm.xml)
> that made your program run ?

This is really an old thread. :)

Something like:

     em.getTransaction().begin();
     Child c = new Child();
     c.setName("Bob");
     c.setParent(em.getReference(Parent.class, 123););
     em.persist(predmet);
     em.getTransaction().commit();

should work. More or less, thats what I'm doing. Maybe you could post 
your code, and exact stack trace?

Regards,
Ognjen

Re: How to PERSIST object without loading references?

Posted by "Edmond M." <ed...@uclouvain.be>.


Ognjen Blagojevic wrote:
> 
> It is, indeed. Thanks.
> 
> Now I really understand why did the specification declared both "find" 
> and "getReference". O:)
> 
> Regards,
> Ognjen
> 
> 
> Patrick Linskey wrote:
>> Hi,
>> 
>> EntityManager.getReference() is your friend here.
>> 
>> -Patrick
>> 
>> On Thu, Apr 3, 2008 at 4:19 AM, Ognjen Blagojevic <og...@etf.bg.ac.yu>
>> wrote:
>>> Hi all,
>>>
>>>  Is there a way to persist an Entity without loading all the referenced
>>> objects?
>>>
>>>  I know that this is possible:
>>>
>>>  Employee e = new Employe();
>>>  e.setName("John Doe");
>>>  e.setIdDepartment(findDepartmentByPrimaryKey(idDept));
>>>  e.setIdRank(findRankByPrimaryKey(idRank));
>>>  // and so on
>>>  em.persist(e);
>>>
>>>  But if I have a lot of references, and lot of INSERTS to do, this
>>> becames
>>> import with poor performace (before each INSERT statemet app must
>>> execute N
>>> selects).
>>>
>>>  It would be much faster if I can set references without looking them
>>> up:
>>>
>>>  Employee e = new Employe();
>>>  e.setName("John Doe");
>>>  Department dept = new Department();
>>>  dept.setIdDepartment(idDept);
>>>  e.setIdDepartment(dept);
>>>  // and so on
>>>  em.persist(e);
>>>
>>>  (Please note here: I'm not trying to insert new department, but rather
>>> to
>>> set a reference to existing one without looking it up in the database.)
>>>
>>>  But this seems impossible. Without CascadeType.PERSIST it throws
>>> something
>>> like:
>>>
>>>  <openjpa-1.0.2-r420667:627158 nonfatal user error>
>>> org.apache.openjpa.persistence.InvalidStateException: Encountered
>>> unmanaged
>>> object "mypackage.Department@18952cc" in persistent field
>>> "mypackage.Employee.idDepartment" of managed object
>>> "mypackage.Employee-5"
>>> during flush.  However, this field does not allow to be
>>> CascadeType.PERSIST.
>>> You cannot flush unmanaged objects.
>>>
>>>  Ok, I add the CascadeType.PERSIST, and then:
>>>
>>>  org.apache.openjpa.persistence.InvalidStateException: The generated
>>> value
>>> processing detected an existing value assigned to this field:
>>> mypackage.Department.idDepartment.  This existing value was either
>>> provided
>>> via an initializer or by calling the setter method.  You either need to
>>> remove the @GeneratedValue annotation or modify the code to remove the
>>> initializer processing.
>>>
>>>
>>>  It must be a way to INSERT objects in the database without looking up
>>> for
>>> all the references, but I am not able to find it.
>>>
>>>  Regards,
>>>  Ognjen
>>>
>> 
>> 
>> 
> 
> 
> 

I've been facing the same kind of problem ; my program keeps complaining
about "unmanaged object" despite using EntityManager.getReference() as
suggested by Patrick. I wonder what I've been doing wrong. Would you show
the piece of code (and possibly the related configuration part in orm.xml)
that made your program run ?

regards !

Edmond/

-- 
View this message in context: http://n2.nabble.com/How-to-PERSIST-object-without-loading-references--tp210631p735154.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: How to PERSIST object without loading references?

Posted by Ognjen Blagojevic <og...@etf.bg.ac.yu>.
It is, indeed. Thanks.

Now I really understand why did the specification declared both "find" 
and "getReference". O:)

Regards,
Ognjen


Patrick Linskey wrote:
> Hi,
> 
> EntityManager.getReference() is your friend here.
> 
> -Patrick
> 
> On Thu, Apr 3, 2008 at 4:19 AM, Ognjen Blagojevic <og...@etf.bg.ac.yu> wrote:
>> Hi all,
>>
>>  Is there a way to persist an Entity without loading all the referenced
>> objects?
>>
>>  I know that this is possible:
>>
>>  Employee e = new Employe();
>>  e.setName("John Doe");
>>  e.setIdDepartment(findDepartmentByPrimaryKey(idDept));
>>  e.setIdRank(findRankByPrimaryKey(idRank));
>>  // and so on
>>  em.persist(e);
>>
>>  But if I have a lot of references, and lot of INSERTS to do, this becames
>> import with poor performace (before each INSERT statemet app must execute N
>> selects).
>>
>>  It would be much faster if I can set references without looking them up:
>>
>>  Employee e = new Employe();
>>  e.setName("John Doe");
>>  Department dept = new Department();
>>  dept.setIdDepartment(idDept);
>>  e.setIdDepartment(dept);
>>  // and so on
>>  em.persist(e);
>>
>>  (Please note here: I'm not trying to insert new department, but rather to
>> set a reference to existing one without looking it up in the database.)
>>
>>  But this seems impossible. Without CascadeType.PERSIST it throws something
>> like:
>>
>>  <openjpa-1.0.2-r420667:627158 nonfatal user error>
>> org.apache.openjpa.persistence.InvalidStateException: Encountered unmanaged
>> object "mypackage.Department@18952cc" in persistent field
>> "mypackage.Employee.idDepartment" of managed object "mypackage.Employee-5"
>> during flush.  However, this field does not allow to be CascadeType.PERSIST.
>> You cannot flush unmanaged objects.
>>
>>  Ok, I add the CascadeType.PERSIST, and then:
>>
>>  org.apache.openjpa.persistence.InvalidStateException: The generated value
>> processing detected an existing value assigned to this field:
>> mypackage.Department.idDepartment.  This existing value was either provided
>> via an initializer or by calling the setter method.  You either need to
>> remove the @GeneratedValue annotation or modify the code to remove the
>> initializer processing.
>>
>>
>>  It must be a way to INSERT objects in the database without looking up for
>> all the references, but I am not able to find it.
>>
>>  Regards,
>>  Ognjen
>>
> 
> 
> 


Re: How to PERSIST object without loading references?

Posted by Patrick Linskey <pl...@gmail.com>.
Hi,

EntityManager.getReference() is your friend here.

-Patrick

On Thu, Apr 3, 2008 at 4:19 AM, Ognjen Blagojevic <og...@etf.bg.ac.yu> wrote:
> Hi all,
>
>  Is there a way to persist an Entity without loading all the referenced
> objects?
>
>  I know that this is possible:
>
>  Employee e = new Employe();
>  e.setName("John Doe");
>  e.setIdDepartment(findDepartmentByPrimaryKey(idDept));
>  e.setIdRank(findRankByPrimaryKey(idRank));
>  // and so on
>  em.persist(e);
>
>  But if I have a lot of references, and lot of INSERTS to do, this becames
> import with poor performace (before each INSERT statemet app must execute N
> selects).
>
>  It would be much faster if I can set references without looking them up:
>
>  Employee e = new Employe();
>  e.setName("John Doe");
>  Department dept = new Department();
>  dept.setIdDepartment(idDept);
>  e.setIdDepartment(dept);
>  // and so on
>  em.persist(e);
>
>  (Please note here: I'm not trying to insert new department, but rather to
> set a reference to existing one without looking it up in the database.)
>
>  But this seems impossible. Without CascadeType.PERSIST it throws something
> like:
>
>  <openjpa-1.0.2-r420667:627158 nonfatal user error>
> org.apache.openjpa.persistence.InvalidStateException: Encountered unmanaged
> object "mypackage.Department@18952cc" in persistent field
> "mypackage.Employee.idDepartment" of managed object "mypackage.Employee-5"
> during flush.  However, this field does not allow to be CascadeType.PERSIST.
> You cannot flush unmanaged objects.
>
>  Ok, I add the CascadeType.PERSIST, and then:
>
>  org.apache.openjpa.persistence.InvalidStateException: The generated value
> processing detected an existing value assigned to this field:
> mypackage.Department.idDepartment.  This existing value was either provided
> via an initializer or by calling the setter method.  You either need to
> remove the @GeneratedValue annotation or modify the code to remove the
> initializer processing.
>
>
>  It must be a way to INSERT objects in the database without looking up for
> all the references, but I am not able to find it.
>
>  Regards,
>  Ognjen
>



-- 
Patrick Linskey
202 669 5907