aspose file tools*
The moose likes EJB Certification (SCBCD/OCPJBCD) and the fly likes Testing @ManyToOne Relationships Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » EJB Certification (SCBCD/OCPJBCD)
Bookmark "Testing @ManyToOne Relationships" Watch "Testing @ManyToOne Relationships" New topic
Author

Testing @ManyToOne Relationships

Niranjan Deshpande
Ranch Hand

Joined: Oct 16, 2005
Posts: 1277
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.


SCJP 1.4 - 95% [ My Story ] - SCWCD 1.4 - 91% [ My Story ]
Performance is a compulsion, not a option, if my existence is to be justified.
Raf Szczypiorski
Ranch Hand

Joined: Aug 21, 2008
Posts: 383
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

Joined: Oct 16, 2005
Posts: 1277
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:




Omar Al Kababji
Ranch Hand

Joined: Jan 13, 2009
Posts: 357
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.


Omar Al Kababji - Electrical & Computer Engineer
[SCJP - 90% - Story] [SCWCD - 94% - Story] [SCBCD - 80% - Story] | My Blog
Niranjan Deshpande
Ranch Hand

Joined: Oct 16, 2005
Posts: 1277
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

Joined: Jan 13, 2009
Posts: 357
then could you place how are your tables from employee and department created in SQL.
Niranjan Deshpande
Ranch Hand

Joined: Oct 16, 2005
Posts: 1277
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

Joined: Jan 13, 2009
Posts: 357
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

Joined: Oct 16, 2005
Posts: 1277
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

Joined: Jan 13, 2009
Posts: 357
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

Joined: Oct 16, 2005
Posts: 1277


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

Joined: Jan 13, 2009
Posts: 357
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

Joined: Oct 16, 2005
Posts: 1277
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!
Adithya Menon
Greenhorn

Joined: Jan 21, 2007
Posts: 19
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.


SCJP1.4(96%) SCWCD1.4(92%)
Niranjan Deshpande
Ranch Hand

Joined: Oct 16, 2005
Posts: 1277
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

al nik
Ranch Hand

Joined: Oct 18, 2007
Posts: 60
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?


SCJP5 - SCWCD5 - SCBCD5
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
 
subject: Testing @ManyToOne Relationships