Avatar billede priestie Nybegynder
19. april 2007 - 12:30

XDoclet og EJB ValueObjects

Hej,

Jeg har søgt som en gal hund for at komme videre med mine VOs. Jeg har også lavet indlæg på et par engelsksprogede forums, men uden noget resultat overhovedet.

Jeg benytter VO's til at sende data fem og tilbage mellem servlets og mine sessionbeans, og det fungerer rigtig fint sålænge det går fra EJB laget til servlets, men når jeg gerne vil opdatere mine Entity beans fra et VO, går det galt.

Jeg benytter autogenererede PKs, og derfor bliver PK ikke automatisk sat når VOs bliver rekvireret fra beanCMP klassen. Derfor smider applikationsserveren en fejl når jeg opdatere en bean der har relationer til atndre beans, da de VOs "hoved" EJB'en relaterer til ikke har fået sat deres PK.

Som det er lige nu er brugen af autogenererede PKs altså et tveægget sværd. At benytte BeanManagedPrimaryKeys kunne sikkert løse problemet, men det ville jeg føle som et nederlag ;)

Problemet:

CustomerEJB -> UserEJB
Customer har relation to User

public CustomerValue CustomerManager.getCustomer(){
...
return getValueObject(customerLocal); // Sætter primary key og retunerer VO
}
Returnerer et CustomerValue objekt, hvor primary key er sat "manuelt" i getValueObject() metoden.

public void updateCustomer(CustomerValue value){
...
customerLocal.setCustomerValue(value);
// Fejler, fordi primary key ikke er sat i UserValue objektet indeholdt i CustomerValue
}

KODEN:

###############################################################
/**
* XDoclet-based CMP 2.x entity bean.  This class must be declared
* public abstract because the concrete class will
* be implemented by the CMP providers tooling.
*
* To generate EJB related classes using XDoclet:
*
*      - Add Standard EJB module to XDoclet project properties
*      - Customize XDoclet configuration
*      - Run XDoclet
*
* Below are the xdoclet-related tags needed for this EJB.
*
* @ejb.bean name="Customer"
*          display-name="Name for Customer"
*          description="Description for Customer"
*          jndi-name="ejb/Customer"
*          primary-key-class="java.lang.Object"
*          type="CMP"
*          cmp-version="2.x"
*          view-type="local"
*             
* @ejb.pk class="java.lang.Object"
* @ejb.util generate="physical"
* @ejb.persistence table-name="Customer"
* @ejb.value-object
*
* @ejb.ejb-external-ref
*    view-type="local"
*    link="User"
*    ref-name="ejb/UserLocal"
*    type="Entity"
*    home="com.tmn.ejb.user.entity.generated.UserLocalHome"
*    business="com.tmn.ejb.user.entity.generated.UserLocal"
* @ejb.ejb-external-ref
*    view-type="local"
*    link="IPPhoneSubscription"
*    ref-name="ejb/IPPhoneSubscriptionLocal"
*    type="Entity"
*    home="com.tmn.ejb.product.entity.generated.IPPhoneSubscriptionLocalHome"
*    business="com.tmn.ejb.product.entity.generated.IPPhoneSubscriptionLocal"
*
* @ejb.finder
*    signature="com.tmn.contentdanmark.ejb.user.entity.generated.CustomerLocal findLocalByUserName(java.lang.String userName)"
*    query="SELECT OBJECT(a) FROM Customer a WHERE ( a.user.userName=?1 )"
*
* @ejb.finder
*    signature="java.util.Collection findAll()"
*    query="SELECT OBJECT(a) FROM Customer a"
*/
public abstract class CustomerEJB implements EntityBean {

  /** The entity context */
  private EntityContext context;
   
  private java.util.Date creationDate;

  /**
    * There are zero or more ejbCreate<METHOD>(...) methods, whose signatures match
    * the signatures of the create<METHOD>(...) methods of the entity bean?s home interface.
    * The container invokes an ejbCreate<METHOD>(...) method on an entity bean instance
    * when a client invokes a matching create<METHOD>(...) method on the entity bean?s
    * home interface.<br>
    *
    * The entity bean provider?s responsibility is to initialize the instance in the ejbCreate<
    * METHOD>(...) methods from the input arguments, using the get and set accessor
    * methods, such that when the ejbCreate<METHOD>(...) method returns, the persistent
    * representation of the instance can be created. <br>
    *
    * The entity bean provider must not attempt to modify the values of cmr-fields in an ejbCreate<
    * METHOD(...) method; this should be done in the ejbPostCreate<METHOD(...) method instead.<br>
    *
    * The entity object created by the ejbCreate<METHOD> method must have a unique primary
    * key. This means that the primary key must be different from the primary keys of all the existing
    * entity objects within the same home. However, it is legal to reuse the primary key of a previously
    * removed entity object. The implementation of the bean provider?s ejbCreate<
    * METHOD>(...) methods should be coded to return a null.<br>
    *
    * An ejbCreate<METHOD>(...) method executes in the transaction context determined by
    * the transaction attribute of the matching create<METHOD>(...) method.
    * The database insert operations are performed by the container within the same
    * transaction context after the Bean Provider?s ejbCreate<METHOD>(...) method completes.
    *
    * @throws CreateException Thrown if method fails due to system-level error.
    * @param creationDate
    *
    * @ejb.create-method
    */
  public java.lang.Object ejbCreate(Date creationDate) throws CreateException {
      this.setCreationDate(creationDate);
      return null;
  }

  /**
    * For each ejbCreate<METHOD>(...) method, there is a matching ejbPostCreate<
    * METHOD>(...) method that has the same input parameters but whose return type is
    * void. The container invokes the matching ejbPostCreate<METHOD>(...) method on
    * an instance after it invokes the ejbCreate<METHOD>(...) method with the same arguments.
    * The instance can discover the primary key by calling getPrimaryKey() on its
    * entity context object. <br>
    *
    * The entity object identity is available during the ejbPostCreate<METHOD>(...)
    * method. The instance may, for example, obtain the component interface of the associated entity
    * object and pass it to another enterprise bean as a method argument.<br>
    *
    * The entity Bean Provider may use the ejbPostCreate<METHOD>(...) to set the values
    * of cmr-fields to complete the initialization of the entity bean instance.
    * An ejbPostCreate<METHOD>(...) method executes in the same transaction context as
    * the previous ejbCreate<METHOD>(...) method.
    *
    * @throws CreateException Thrown if method fails due to system-level error.
    */
  public void ejbPostCreate(Date creationDate) throws CreateException {
  }

  public void ejbActivate() throws EJBException, RemoteException {
      // TODO Auto-generated method stub

  }

  public void ejbLoad() throws EJBException, RemoteException {
      // TODO Auto-generated method stub

  }

  public void ejbPassivate() throws EJBException, RemoteException {
      // TODO Auto-generated method stub

  }

  public void ejbRemove()
      throws RemoveException,
      EJBException,
      RemoteException {
      // TODO Auto-generated method stub

  }

  public void ejbStore() throws EJBException, RemoteException {
      // TODO Auto-generated method stub

  }

  /**
    * Set the associated entity context. The container calls this method
    * after the instance creation. The entity bean must not attempt to
    * access its persistent state and relationships using the accessor
    * methods during this method. <br>
    *
    * The enterprise bean instance should store the reference to the context
    * object in an instance variable. <br>
    *
    * This method is called with no transaction context.
    *
    * @throws EJBException Thrown if method fails due to system-level error.
    */
  public void setEntityContext(EntityContext newContext) throws EJBException {
      context = newContext;
  }

  /**
    * Unset the associated entity context. A container invokes this method
    * before terminating the life of the instance. The entity bean must not
    * attempt to access its persistent state and relationships using the
    * accessor methods during this method. <br>
    *
    * This method is called with no transaction context.
    *
    * @throws EJBException Thrown if method fails due to system-level error.
    */
  public void unsetEntityContext() throws EJBException {
      context = null;
  }

  /**
    * @return the creationDate
    *
    * @ejb.persistence
    * @ejb.interface-method view-type="both"
    */
  public abstract java.util.Date getCreationDate();
  /**
    * @param creationDate the creationDate to set
    *
    * @ejb.interface-method view-type="both"
    */
  public abstract void setCreationDate(java.util.Date creationDate);

      /**
      * @ejb.value-object
    *    compose="com.tmn.ejb.user.entity.generated.UserValue"
    *    compose-name="UserValue"   
      *
      * @ejb.relation
      *    name="Customer-User"
      *    role-name="Customer-CanBe-User"
      *    target-ejb="User"
      *    target-role-name="User-CanBeA-Customer"
      *
      * @ejb.interface-method view-type="both"
      */
      public abstract com.tmn.ejb.user.entity.generated.UserLocal getUser();
      /**
      * @ejb.interface-method view-type="local"
      */
      public abstract void setUser(com.tmn.ejb.user.entity.generated.UserLocal user);

      /**
      * @ejb.value-object
    *    compose="com.tmn.ejb.product.entity.generated.IPPhoneSubscriptionValue"
    *    compose-name="IPPhoneSubscriptionValue"   
      *
      * @ejb.relation
      *    name="Customer-IPPhoneSubscription"
      *    role-name="Customer-CanHave-IPPhoneSubscription"
      *    target-ejb="IPPhoneSubscription"
      *    target-role-name="IPPhoneSubscription-BelongsTo-Customer"
      *
      * @ejb.interface-method view-type="both"
      */
      public abstract com.tmn.ejb.product.entity.generated.IPPhoneSubscriptionLocal getIPPhoneSubscription();
      /**
      * @ejb.interface-method view-type="local"
      */
      public abstract void setIPPhoneSubscription(com.tmn.ejb.product.entity.generated.IPPhoneSubscriptionLocal iPPhoneSubscription);
     
      /**
      * Return the value object version of this entity.
      *
      * @ejb.interface-method view-type="local"
      */
      public abstract com.tmn.contentdanmark.ejb.user.entity.generated.CustomerValue getCustomerValue();
     
      /**
      * Set the value object version of this entity.
      *
      * @ejb.interface-method view-type="local"
      */
      public abstract void setCustomerValue(com.tmn.contentdanmark.ejb.user.entity.generated.CustomerValue value);
}
##############################################################

Jeg smider 200 point efter et svar, selvom det burde honnoreres med mere, da jeg godt er klar over at spørgsmålet er lidt langhåret :)

priest
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester