cancel
Showing results for 
Search instead for 
Did you mean: 

Can't remove related Entity EJB when the foreign key is a CMP field

Former Member
0 Kudos

I've a relationship between bean EmployeeBean and DeparmentBean (n:1), with a CMR field defined in Employee called 'deparment'.

I've a CMP field in EmployeeBean which is the foreign key itself, called 'depId'.

(It's easier to work putting the id in this field, than finding the correct instance of DepartmentBean to set a relation).

I can't remove the relation from the employee. I've never had this problem with other application servers. I still thinks there are some things wrong with the EJB implementation of SAP WAS.

a) This makes nothing, cos depId keeps its value:

EmployeeBean employee = employeeHome.find..

employee.setDepartment(null);

b) This throws an exception:

EmployeeBean employee = employeeHome.find..

employee.setDepId(null); // The same occurs if I setDeparment(null) too

The exception is:

java.lang.NullPointerException

at java.util.Hashtable.get(Hashtable.java:333)

at com.sap.engine.services.ejb.entity.pm.TransactionalPersistentCache.get(TransactionalPersistentCache.java:38)

at com.sap.engine.services.ejb.entity.pm.PersistentCache.supply(PersistentCache.java:81)

at com.giasa.giares.ejb.RegistroBean0PM.setDepId(EmployeeBean0PM.java:325)

...

I use NW04sSR1 and Oracle 9.2.0.7 with driver at native level.

It seems there is an intermediate cache messing the remove. How can I disable or flush this cache? Or simply, how can I remove the relation?

Thanks in advance.

Accepted Solutions (0)

Answers (1)

Answers (1)

Vlado
Advisor
Advisor
0 Kudos

Hi Aníbal,

If I understand you right, you have mapped two fields - the CMP field 'depId' and the CMR field 'department' - to one and the same column in the EMPLOYEE table (please correct me if I'm wrong).

Well, this is allowed, but care should be taken when working with these two fields and some restrictions apply.

b) This throws an exception:

EmployeeBean employee = employeeHome.find..

employee.setDepId(null); // The same occurs if I setDeparment(null) too

The most important thing to notice is that you can update the relation only through the CMR field, i.e. employee.setDeparment(null). If you try to update the CMP field, the EJB container tries to find the related Department entity with that primary key (in order to keep the relation consistent) and since you pass null you receive a NullPointerException.

a) This makes nothing, cos depId keeps its value:

EmployeeBean employee = employeeHome.find..

employee.setDepartment(null);

This should work. Have you committed the transaction before calling employee.getDepId()?

BTW,

(It's easier to work putting the id in this field, than finding the correct instance of DepartmentBean to set a relation).

if you know the id (primary key) of the required DepartmentBean, it's pretty straightforward to find the corresponding instance just by calling departmentHome.findByPrimaryKey(id). So, you don't really need another field to store the id. This makes things concerning relationship management a lot simpler.

Hope this helps!

-Vladimir

Former Member
0 Kudos

You got it correctly. But there is no excuse

b) Why does the container check the relation before doing the commit? The container should update the fields, realize the foreign key has become null, before trying to find the related bean in the cache, and then remove the relation. (This seems like a bug in the persistent manager)

a) I don't call getDepId() into the transactional method, in which I setDeparment to null. It commits of course. I found that when it makes an update, it updates all the fields of the bean, although you have changed them or not. (This seems to be very inneficient). When I load the bean employee, it loads the field depId. Although I've set the CMR to null, when it stores all the fields (including depId), the relation persist cos the value of field depId remains the same. It seems to get the value of this field after getting the value of the relation foreign key, before setting the update statement.

Well, I think to be looking for instances of the related beans constantly, introduces a lot of database overhead, when I don't want to load the related bean, only set the relation.

The fact is that I've been working with others applicattion servers, like jboss or websphere, with no problem in such a operation. And this isn't nothing out the j2ee standard. It seems like a confusion in the order of the steps to make a bean persistent, or managing the intermediate cache.

The only way I got it to work, is removing the depId field, this maked my code bigger cos the exception control, and slower cos the database overhead.

Thanks.

Best regards.

Vlado
Advisor
Advisor
0 Kudos

Hi Aníbal,

Thanks for your feedback so far! I consider some of your points valuable and we will discuss them.

Meanwhile, have you already tried the new SAP NetWeaver AS, Java EE 5 Edition ? One of its key features is the implementation of the new Java Persistence API - the unified and simplified lightweight persistence model for both Java EE and Java SE. Entity persistence is much easier and streamlined with EJB 3.0 and JPA than with EJB 2.x!

Best regards,

Vladimir

Former Member
0 Kudos

Yep, I've seen it. I'm impatient to check it out. The matter is that I'm pretty fallen in love with webdynpro runtime, which is my daily work. It's a pitty to continue fighting with jdk 1.4 and an older version of eclipse.

Kind regards.

Aníbal