• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Testing @ManyToOne Relationships

 
Ranch Hand
Posts: 1277
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all,

I am trying to test a @ManyToOne relationship. I am using a stateless session bean for this. I have written two entities:

Employee
Department

I am pasting the relevant code here:






The bean-


The client




When I run the client, I get this error:
object references an unsaved transient instance - save the transient instance before flushing: com.example.Employee.department -> com.example.Department

I am saving two employee objects having the same department. IS this the correct way to do?

My intention is, when I same many employess, that work in a single department, te department table should be populated with a single row, with the employee table's foreign key pointing to the Department table's primary key. i.e. the DEPARTMENT_ID col. of the Employee table will contain values = the primary key of the single row in the Department table..

Please let me know the approach.
 
Ranch Hand
Posts: 383
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
For the first employee, the department is not saved, and it fails. You either have to save it before employees, or set cascade to ALL or PERSIST on the @ManyToOne.


Raf
 
Niranjan Deshpande
Ranch Hand
Posts: 1277
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Raf,

I tried it this way:

1. In the client -



Again, I got the same exception.

2. I then used the CASCADE as PERSIST on the Employee entity. But I got the same exception as used this in the client:




 
Ranch Hand
Posts: 357
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
is the Department entity you are setting for the user persistent, or detached ? i think that your Department instance "d1" is not yet persisted. so you have to persist "d1" before persisting "e1" and "e2".

for a quick test try doing



and see if it works or not. if it works then this is your problem. and you have to either always persist a department before setting it to an employee, or define a cascade property for the many-to-one relationship so it will be done automatically for you.
 
Niranjan Deshpande
Ranch Hand
Posts: 1277
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Omar,

That is what I have done in Approach 1. I have persisted the department first by saying


- this internally calls em.persist(d) in the 'relation' stateless bean

Then I set this departement on both the employees and then say



- both these intercally do a em.persist(e),

where em is the entity manager in the bean. In the bean i have defined seperate methods to save the employee and the department!

In the HSQL databas I can see that 'department' is persisted in the database, but the exception comes when I save the employee. I wonder why it comes inspite of the departement being persisted.
 
Omar Al Kababji
Ranch Hand
Posts: 357
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
then could you place how are your tables from employee and department created in SQL.
 
Niranjan Deshpande
Ranch Hand
Posts: 1277
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The table DEPARTMENT

ID (primary key)
NAME
DESCRIPTION


The table EMPLOYEE

ID (primary key)
NAME
SALARY
DEPARTMENT_ID
(foreign key to the DEPARTMENT) table
 
Omar Al Kababji
Ranch Hand
Posts: 357
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
mmm it looks everything is perfect, i would suggest these things

1) if you just persist a department, go to the DB and check if it really saved the department in its corresponding table or not.
2) try to remove the @JoinColumn annotation in the empolyee entity.
3) if nothing works try changing the @ManyToOne and make it @OneToOne
4) if nothing still happens try to change the names of the tables.
 
Niranjan Deshpande
Ranch Hand
Posts: 1277
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

omar al kababji wrote:mmm it looks everything is perfect, i would suggest these things

1) if you just persist a department, go to the DB and check if it really saved the department in its corresponding table or not.
2) try to remove the @JoinColumn annotation in the empolyee entity.
3) if nothing works try changing the @ManyToOne and make it @OneToOne
4) if nothing still happens try to change the names of the tables.



1) <- this works fine
I am not in favour of doing 2) as this would defy my intention of defining relationship between two entities.
I am not in favour of doing 3) as I want to test @ManyToOne
AS far as 4) is concerned, ff the 'default' table names work for my other ejb code, what would changing the tables do any good to me!

Finally I tried saving the department, and then saving the employee without the departement. As expected, the department_id col in the employee table was blank!

I am clueless now

 
Omar Al Kababji
Ranch Hand
Posts: 357
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
for the JoinColumn is used to tell which is the column used for the join and you should specify the name in the JoinColumn, and the default value would be the name of the property followed with the _id so it is department_id and its the same in your SQL so not putting the JoinColumn will not effect anything. its used only when the join column was for example dept_id at this point you would need to specify it.
 
Niranjan Deshpande
Ranch Hand
Posts: 1277
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Considering the code again. Line A saves the department with say Id=1. Now in lines B and C I try to set the same department in the Employee e1 and e2 objects. On debugging I found that in the setDepartment( ) method, the d1 object's id is 0 and not 1. That is the reason why a association is not established.

What might be the reason? I expect that d1 obj with id. 1 should be saved in the employee table in two rows with
department_id = 1 in each row. But its being saved with department_id=0. I want to get a hold of the d1 obj with pk = 1 to be set in the employee obj. but this is not happening!
 
Omar Al Kababji
Ranch Hand
Posts: 357
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Are you sure that your GeneratedValue strategy on the id is working well ? if it returns 0 there is a big chance that its not doing what its supposed to do.
 
Niranjan Deshpande
Ranch Hand
Posts: 1277
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When the department is persited, id = 1. So its working fine.

But when I persit this in the the employee, i expect it to have id = 1, but a 0 primary key departement is being set in the employee.

I am facing the same problem in pro EJB Chapter 3 code!
 
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Niru,
I think your Department class is getting default values during the object Creation.
After saving Department object try to load it again before setting into employee object then only primary key will be present.
 
Niranjan Deshpande
Ranch Hand
Posts: 1277
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was reading Pro EJB3 chapter 5. I came to know that my Departement instance was around but was not managed, as the persistence context associate with the saveDepartment( ) method goes away, the moment the methd returns. So the Department obj was not available when I set it in Employee.

To overcome this, I used . Extended Persistence Contexts allow you to keep entity instances managed beyond single method calls and transaction boundaries.

So the Department object saved by the bean was available to the client when it did employee.setDepartment(d);

Now the last hiccup in the code is: If I save two employees with the same department, I expect 2 rows in EMPLOYEE and 1 in DEPARTMENT. Currently, I am getting 2 rows in both tables, with DEPT_ID=1,2 matching with the ID =1,2 (PK) of the DEPARTMENT. I expect, DEPT_ID=1,1 in EMPLOYEE where 1=ID: PK of the Employee.

What am I missing?

@Adithya Menon: Please check your PM

 
Ranch Hand
Posts: 60
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
try to set the department returned from saveDepartment (it should return the obj you get when persist() is called).. the instance you have doesn't hold the persisted id (I suppose hibernate is autogenerating this for you). something like this?
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic