Good pattern for persistence from clients?

Discussions

EJB design: Good pattern for persistence from clients?

  1. Good pattern for persistence from clients? (4 messages)

    I realize that this is more of a general design issue than an EJB specific issue. However, I'm doing the work in EJB's, so I figured at least see if there were any thoughts here.

    I'm working on a Java GUI using EJBs to push the logic on the server side. I'm using BMP entity beans, and a mixture of stateful and stateless session beans.

    In order to decrease network traffic when fetching and saving data, I only access entity beans within session beans. I call into the session bean from the GUI. The session bean collects the appropriate entity beans. In this instance, let's suppose it collects a collection of AddressBeans. Our entity beans return a flat object representation of that bean, in this case, AddressDO. We do this to avoid the network traffic of the get() and set() methods on the bean. The session bean then returns a collection of AddressDO's (which were obtained from the collection of AddressBeans it had retrieved).

    We wish for the client to be able to modify these AddressDO's, and then submit them to a session bean so that any changes can be persisted to the database. The session bean would take an AddressDO, find the appropriate AddressBean, set the values on the bean to match those of the AddressDO, and then save the bean. Unfortunately, we haven't found a great way to do this.

    First of all, I retrieve the PK (AddressID, an integer) to use in finding the AddressBean to be updated from the AddressDO that's passed in. It would be quite easy for the client to alter the AddressID, and hence update the wrong AddressBean.

    Second, we want to avoid saving changes to an old version of an address. Meaning, if I fetch address #1, immediately after somebody updates address#1, I don't want to be able to save changes to Address #1 again - as my changes were made to an old address.

    I'm currently using an ugly solution to the problem. I'm creating a hash value that is unique to each AddressBean - and placing this value in each AddressDO that I send out. When somebody submits an AddressDO for persistence, I find the corresponding AddressBean, get the hash value, and compare it to the hash value on the AddressDO. If the hashes are the same, then both objects represent the same Address - and the data has not been altered prior to my save. If the hash values don't match up, then either the PK has been altered, or the data has been altered after that AddressDO was corrected.

    I figure this isn't optimal, as I'm calculating quite a few hash values - which manages to waste some CPU time. I'm also piggy backing that data onto the AddressDO - with no value being added to the GUI actually making use of these DO objects.

    Does anyone know of a pattern I should look to for guidance? Any comments that might be helpful?

    Thanks for your time,
    -Dortman
  2. One thing you can do is to make the data members of the AddressDO object private and do not provide setter methods for the primary key. This will ensure that no one can modify the primary key.
    For the hash code problem the only other option is to use the last modified timestamp in the database and the bean if you can live with milli second acuracy.
  3. Thanks for the reply, Raghu.

    <
    Actually, I initially did just this. However, we might also need to share our AddressDO object with other non-Java clients via CORBA. As this is the case, we made the AddressDO flat so that we could transfer it as a CORBA struct to minimize network traffic. This being the case, I don't have the option of keeping attribute private. :(

    <
    Ah, that's a good idea. I didn't think of that.

    However, brining the whole CORBA thing into the equation again - the timestamp would be a attribute which could be modified by the CORBA client before passing it back in for persistence. That being the case, it would be possible for the client to alter the timestamp, making persistence a success when it shouldn't be.

    I guess I should have mentioned the CORBA aspect, as it does complicate things slightly.

    Is the current approach that we're taking not that far out there given the requirements? I thought there might be a better way - but perhaps there isn't.

    Thanks again,
    -Dortman
  4. Oops, it seems that the posting logic here doesn't like it when one uses double "<
    Again:
    -- One thing you can do is to make the data members of the AddressDO object private and do not provide setter methods for the primary key. This will ensure that no one can modify the primary key. --

    Actually, I initially did just this. However, we might also need to share our AddressDO object with other non-Java clients via CORBA. As this is the case, we made the AddressDO flat so that we could transfer it as a CORBA struct to minimize network traffic. This being the case, I don't have the option of keeping attribute private. :(

    -- For the hash code problem the only other option is to use the last modified timestamp in the database and the bean if you can live with milli second acuracy. --

    Ah, that's a good idea. I didn't think of that.

    However, brining the whole CORBA thing into the equation again - the timestamp would be a attribute which could be modified by the CORBA client before passing it back in for persistence. That being the case, it would be possible for the client to alter the timestamp, making persistence a success when it shouldn't be.

    I guess I should have mentioned the CORBA aspect, as it does complicate things slightly.

    Is the current approach that we're taking not that far out there given the requirements? I thought there might be a better way - but perhaps there isn't.

    Thanks again,
    -Dortman
  5. I am not good at corba, but will making some attributes you dont want modified "final" help.