persistence@glassfish.java.net

Re: Need a reference to an Session Bean within an Entity Bean

From: Marina Vatkina <Marina.Vatkina_at_Sun.COM>
Date: Fri, 03 Aug 2007 13:12:35 -0700

Kem,

Kem Elbrader wrote:
> Sorry I'm not sure all of code I tried to send before made it and I
> don't think my explanation was very clear. Here's a second attempt. :)
>
> I have an entity that is represented in a third parties database and
> the only access I have to it is through a web service. I can't change
> the third parties schema. I need to add some data (properties) to the
> entity and would like to use JPA to do so. I'm considering using the
> PostLoad and PostPersist annotation to populate and save/update the
> data in the third party database to the entity which I create using
> JPA.

You'll need to also listen to PostUpdate and may be PostRemove.

>
> Below is a modified version of what I sent originally (hopefully it's
> a little easier to understand). Do you think that the solution below
> is a good idea? I've realized a couple of possible issues. As far as I
> know this method won't participate in the transaction that JPA uses
> and couldn't roll back changes in case of an error.

Why do you think that they are not part of the transaction?

  Also there is
> nothing to guarantee referential integrity... but I think that's more
> of a problem with relating data in two different DBMSs.

You can use 2 PUs with 2 EMs and a single facade that hides from the user the
fact that they are working with 2 completely different entities.

thanks,
-marina

>
> @Entity class User {
>
> @Id String id;
> @Transient int externalId; // acts as a "foreign key" into the third
> party's db
> @Transient String name; // existing data
> int newData; // new data
>
> @Transient WebServicePort port;
>
> User() {
> WebService service = new WebService();
> port = service.getWebServicePort();
> }
>
> // getters/setters for properties
>
> @PostLoad void initializeUser() {
> Rep rep = port.findRep(externalId); // get needed data from ws
> this.setName(rep.getName()); // copy data to transient field
> }
>
> @PostPersist void saveUser() {
> Rep rep = new Rep();
> rep.setId(externalId);
> rep.setName(name);
> port.persist(rep); // saves or updates using ws
> }
> }
>
> On 8/1/07, Marina Vatkina <Marina.Vatkina_at_sun.com> wrote:
>
>>I'm not sure that I understand it correctly. If you don't want to map a field to
>>a column in a database, you do mark it as @Transient. But do you plan to
>>override it in orm.xml later on? If not, what's the purpose of such field?
>>
>>thanks,
>>-marina
>>
>>Kem Elbrader wrote:
>>
>>>I understand that @Transient "means" don't populate and don't write
>>>but I need a way to keep JPA from populating the field since it
>>>doesn't even exist in the database that JPA is using.
>>>Would updateable=false do this? Is there another way to mark a field
>>>as not being used by JPA that doesn't "mean" that it won't be
>>>persisted somewhere?
>>>
>>>On 7/31/07, Marina Vatkina <Marina.Vatkina_at_sun.com> wrote:
>>>
>>>
>>>>Kem,
>>>>
>>>>You should be able to mark the existing fields as 'updateable=false' but
>>>>@Transient means not only to skip during write to the database, but also never
>>>>populate during the read.
>>>>
>>>>Regards,
>>>>-marina
>>>>
>>>>Kem Elbrader wrote:
>>>>
>>>>
>>>>>Here's the situation.
>>>>>
>>>>>A company uses a database that stores information about its customers.
>>>>>A web interface is available for customer service representatives to
>>>>>update the customers name, phone number, etc. The web interface is not
>>>>>suitable for customers to use so the company has a calling center that
>>>>>enables the customers to request changes. The database and web
>>>>>interface were produced by a third party which is unwilling to make
>>>>>changes to the existing system. The third party does provide a web
>>>>>service with operations to create, update, and delete the data.
>>>>>
>>>>>The company wants to provide a web interface to allow customers to
>>>>>update their information themselves. Further, the company wants to
>>>>>produce additional services which will require extra data that is not
>>>>>stored in the original database. For example, some of the entities
>>>>>represented in the original database simply need some properties added
>>>>>to them. It's not viable to reproduce the existing system. So a new
>>>>>system must be created that is capable of updating the data in the
>>>>>existing system, persist the new data and provide the new
>>>>>functionality.
>>>>>
>>>>>I was hoping I could use JPA to model the new and old data together so
>>>>>that a single object could be used in the cases where simple
>>>>>properties need to be added to the existing entities. Is this
>>>>>reasonable?
>>>>>
>>>>>Here is my current approach.
>>>>>
>>>>>@Entity
>>>>>@EntityListeners({UserListener.class})
>>>>>class ExampleUser {
>>>>> @Id String login; // new data
>>>>> @Transient String name; // existing data
>>>>>
>>>>> String getLogin() { return login; }
>>>>> void setLogin(String login) { this.login= login; }
>>>>>
>>>>> String getName() { return name; }
>>>>> void setName(String name) { this.name = name; }
>>>>>}
>>>>>
>>>>>class UserListener {
>>>>> @PostLoad void initializeUser(Object entity) {
>>>>> // use web service to obtain the users name
>>>>> // copy the name to ExampleUser.name
>>>>> }
>>>>> @PostPersist void saveUser(Object entity) {
>>>>> // use web service to save ExampleUser.name
>>>>> }
>>>>>}
>>>>>
>>>>>I believe this is similar to your suggestion but I'm not quite sure
>>>>>what you meant. Can you clarify your suggestion?
>>>>>
>>>>>On 7/30/07, Craig L Russell <Craig.Russell_at_sun.com> wrote:
>>>>>
>>>>>
>>>>>
>>>>>>Hi Kem,
>>>>>>
>>>>>>Can you model this as an EJB that is created by other EJBs and that
>>>>>>contacts the third party web service plus the Entity?
>>>>>>
>>>>>>Craig
>>>>>>
>>>>>>On Jul 30, 2007, at 11:47 AM, Kem Elbrader wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>I have an entity which has a few properties that aren't persisted to
>>>>>>>the database but rather obtained from a third party web service. How
>>>>>>>would you suggest going about accomplishing this?
>>>>>>>
>>>>>>>On 7/30/07, Craig L Russell <Craig.Russell_at_sun.com> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>Hi Kem,
>>>>>>>>
>>>>>>>>I'd suggest you rework your design such that you only use references
>>>>>>>>"from" EJBs "to" Entities and other EJBs.
>>>>>>>>
>>>>>>>>Having Entities reference EJBs violates the basic POJO model.
>>>>>>>>
>>>>>>>>Regards,
>>>>>>>>
>>>>>>>>Craig
>>>>>>>>
>>>>>>>>On Jul 30, 2007, at 11:22 AM, Kem Elbrader wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>>Is it possible to inject an EJB into an Entity? If not is there
>>>>>>>>>another way to get a reference to a EJB from an Entity?
>>>>>>>>>
>>>>>>>>>Example:
>>>>>>>>>
>>>>>>>>>@Entity
>>>>>>>>>public class Customer {
>>>>>>>>>
>>>>>>>>> @EJB
>>>>>>>>> CustomerAction customerAction;
>>>>>>>>>
>>>>>>>>> @PostLoad
>>>>>>>>> void initialize() {
>>>>>>>>> // do stuff with customerAction...
>>>>>>>>> }
>>>>>>>>>}
>>>>>>>>
>>>>>>>>Craig Russell
>>>>>>>>Architect, Sun Java Enterprise System http://java.sun.com/products/
>>>>>>>>jdo
>>>>>>>>408 276-5638 mailto:Craig.Russell_at_sun.com
>>>>>>>>P.S. A good JDO? O, Gasp!
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>
>>>>>>Craig Russell
>>>>>>Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
>>>>>>408 276-5638 mailto:Craig.Russell_at_sun.com
>>>>>>P.S. A good JDO? O, Gasp!
>>>>>>
>>>>>>
>>>>>>
>>>>