Jave-EJB-CMP Projekt mit Compostie Key

GartenUmgraben

Erfahrenes Mitglied
Moin.. in meinem Projekt habe ich in einer Tabell einen Composite Primary Key über zwei Spalten. Dementsprechend habe ich eine Extra Klasse dafür geschrieben. Wenn ich den Kram nun deploye dann scheint beim Create Table Statement der Primary Key nicht gesetzt wird.

Code:
java.sql.SQLException: Unexpected token: ) in statement [CREATE TABLE KANTEN (id INTEGER NOT NULL, nachbar INTEGER NOT NULL, wert INTEGER NOT NULL, status INTEGER NOT NULL, CONSTRAINT PK_KANTEN PRIMARY KEY ())]
Sprich die Klammer bei .. Primary Key().. im Create Statement is leer.

Was muss ich in den interfaces/Bean/xmls beachten damit das Statement richtig kreiert wird ?

Code:
package ueb1.ejb;

import java.rmi.RemoteException;

import javax.ejb.EJBException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import javax.ejb.RemoveException;

import ueb1.utils.KantenPK;

/**
 * @ejb.bean name="Kanten"
 *           display-name="Name for Kanten"
 *           description="Description for Kanten"
 *           jndi-name="ejb/Kanten"
 *           prim-key-class="ueb1.utils.KantenPK"
 *           type="CMP"
 *           cmp-version="2.x"
 *           view-type="local"
 */
public abstract class KantenEJB implements EntityBean {

	public KantenEJB() {
		super();
		// TODO Auto-generated constructor stub
	}

	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

	}

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

	}

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

	}

	/**
	 * Getter for CMP Field id
	 *
	 * @ejb.pk-field
	 * @ejb.persistent-field
	 * @ejb.interface-method   view-type="local"
	 */
	public abstract int getId();

	/**
	 * Setter for CMP Field id
	 *
	 * @ejb.interface-method   view-type="local"
	 */
	public abstract void setId(int value);

	/**
	 * Getter for CMP Field nachbar
	 *
	 * @ejb.pk-field
	 * @ejb.persistent-field
	 * @ejb.interface-method   view-type="local"
	 */
	public abstract int getNachbar();

	/**
	 * Setter for CMP Field nachbar
	 *
	 * @ejb.interface-method   view-type="local"
	 */
	public abstract void setNachbar(int value);

	/**
	 * Getter for CMP Field wert
	 *
	 * 
	 * @ejb.persistent-field
	 * @ejb.interface-method   view-type="local"
	 */
	public abstract int getWert();

	/**
	 * Setter for CMP Field wert
	 *
	 * @ejb.interface-method   view-type="local"
	 */
	public abstract void setWert(int value);

	/**
	 * Getter for CMP Field status
	 *
	 * 
	 * @ejb.persistent-field
	 * @ejb.interface-method   view-type="local"
	 */
	public abstract int getStatus();

	/**
	 * Setter for CMP Field status
	 *
	 * @ejb.interface-method   view-type="local"
	 */
	public abstract void setStatus(int value);

	/**
	 * Create method
	 * @ejb.create-method  view-type = "local"
	 */
	public KantenPK ejbCreate(int id, int nachbar) throws javax.ejb.CreateException {
		// TODO Auto-generated method stub
		setId(id);
		setNachbar(nachbar);
		return null;
	}
	/**
	 * Post Create method
	 */
	public void ejbPostCreate(int id, int nachbar)
		throws javax.ejb.CreateException {
		// TODO Auto-generated method stub
	}
}
>

Code:
package ueb1.interfaces;

/**
 * Local home interface for Kanten.
 */
public interface KantenLocalHome
   extends javax.ejb.EJBLocalHome
{
   public static final String COMP_NAME="java:comp/env/ejb/KantenLocal";
   public static final String JNDI_NAME="KantenLocal";

   public ueb1.interfaces.KantenLocal create(int id , int nachbar)
      throws javax.ejb.CreateException;

   public ueb1.interfaces.KantenLocal findByPrimaryKey(ueb1.utils.KantenPK pk)
      throws javax.ejb.FinderException;

}

Code:
/*
 * Generated by XDoclet - Do not edit!
 */
package ueb1.interfaces;

/**
 * Local interface for Kanten.
 */
public interface KantenLocal
   extends javax.ejb.EJBLocalObject
{
   /**
    * Getter for CMP Field id
    */
   public int getId(  ) ;

   /**
    * Setter for CMP Field id
    */
   public void setId( int value ) ;

   /**
    * Getter for CMP Field nachbar
    */
   public int getNachbar(  ) ;

   /**
    * Setter for CMP Field nachbar
    */
   public void setNachbar( int value ) ;

   /**
    * Getter for CMP Field wert
    */
   public int getWert(  ) ;

   /**
    * Setter for CMP Field wert
    */
   public void setWert( int value ) ;

   /**
    * Getter for CMP Field status
    */
   public int getStatus(  ) ;

   /**
    * Setter for CMP Field status
    */
   public void setStatus( int value ) ;

}

Code:
/**
 * 
 */
package ueb1.utils;

import java.io.Serializable;


/**
 * @author Daniel
 *
 */
public class KantenPK implements Serializable {

	private int id;
	private int nachbar; 
	
	/**
	 * 
	 */
	public KantenPK() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	public KantenPK(int newId, int newNachbar) {
		this.id = newId;
		this.nachbar = newNachbar;
	}
	
	public void setId(int newId) {this.id = newId;}
	public void setNachbar(int newNachbar){this.nachbar = newNachbar;}
	
	public int getId(){return this.id;}
	public int getNachbar(){return this.nachbar;}
	
	public boolean equals(Object obj) {
		if( this.getClass().equals(obj.getClass())) {
			KantenPK other = (KantenPK) obj;
			return( this.id == other.getId() &&
					this.nachbar == other.getNachbar());
		}
		return false;
	}
	
	public int hashCode() {
		return (Integer.toString(this.id) + Integer.toString(this.nachbar)).hashCode();
	}

}
Code:
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">

<ejb-jar >

   <description><![CDATA[No Description.]]></description>
   <display-name>Generated by XDoclet</display-name>

   <enterprise-beans>

      <!-- Session Beans -->
      <session >
         <description><![CDATA[Description for TrafficLight]]></description>
         <display-name>Name for TrafficLight</display-name>

         <ejb-name>TrafficLight</ejb-name>

         <home>ueb1.interfaces.TrafficLightHome</home>
         <remote>ueb1.interfaces.TrafficLight</remote>
         <ejb-class>ueb1.ejb.TrafficLightEJB</ejb-class>
         <session-type>Stateful</session-type>
         <transaction-type>Container</transaction-type>

      </session>

      <session >
         <description><![CDATA[Description for Umrech]]></description>
         <display-name>Name for Umrech</display-name>

         <ejb-name>Umrech</ejb-name>

         <home>ueb1.interfaces.UmrechHome</home>
         <remote>ueb1.interfaces.Umrech</remote>
         <ejb-class>ueb1.ejb.UmrechEJB</ejb-class>
         <session-type>Stateless</session-type>
         <transaction-type>Container</transaction-type>

         <env-entry>
            <env-entry-name>param/envTest</env-entry-name>
            <env-entry-type>java.lang.String</env-entry-type>
            <env-entry-value><![CDATA[env-entry aus der UmrechEJB]]></env-entry-value>
         </env-entry>

      </session>

     <!--
       To add session beans that you have deployment descriptor info for, add
       a file to your XDoclet merge directory called session-beans.xml that contains
       the <session></session> markup for those beans.
     -->

      <!-- Entity Beans -->
      <entity >
         <description><![CDATA[Description for Kanten]]></description>
         <display-name>Name for Kanten</display-name>

         <ejb-name>Kanten</ejb-name>

         <local-home>ueb1.interfaces.KantenLocalHome</local-home>
         <local>ueb1.interfaces.KantenLocal</local>

         <ejb-class>ueb1.ejb.KantenEJB</ejb-class>
         <persistence-type>Container</persistence-type>
         <prim-key-class>ueb1.utils.KantenPK</prim-key-class>
         <reentrant>False</reentrant>
         <cmp-version>2.x</cmp-version>
         <abstract-schema-name>Kanten</abstract-schema-name>
         <cmp-field >
            <description><![CDATA[Getter for CMP Field id]]></description>
            <field-name>id</field-name>
         </cmp-field>
         <cmp-field >
            <description><![CDATA[Getter for CMP Field nachbar]]></description>
            <field-name>nachbar</field-name>
         </cmp-field>
         <cmp-field >
            <description><![CDATA[Getter for CMP Field wert]]></description>
            <field-name>wert</field-name>
         </cmp-field>
         <cmp-field >
            <description><![CDATA[Getter for CMP Field status]]></description>
            <field-name>status</field-name>
         </cmp-field>

	  <!-- Write a file named ejb-finders-KantenEJB.xml if you want to define extra finders. -->

      </entity>

      <entity >
         <description><![CDATA[Description for Knoten]]></description>
         <display-name>Name for Knoten</display-name>

         <ejb-name>Knoten</ejb-name>

         <local-home>ueb1.interfaces.KnotenLocalHome</local-home>
         <local>ueb1.interfaces.KnotenLocal</local>

         <ejb-class>ueb1.ejb.KnotenEJB</ejb-class>
         <persistence-type>Container</persistence-type>
         <prim-key-class>java.lang.Integer</prim-key-class>
         <reentrant>False</reentrant>
         <cmp-version>2.x</cmp-version>
         <abstract-schema-name>Knoten</abstract-schema-name>
         <cmp-field >
            <description><![CDATA[Getter for CMP Field name]]></description>
            <field-name>name</field-name>
         </cmp-field>
         <cmp-field >
            <description><![CDATA[Getter for CMP Field id]]></description>
            <field-name>id</field-name>
         </cmp-field>
         <cmp-field >
            <description><![CDATA[Getter for CMP Field mapX]]></description>
            <field-name>mapX</field-name>
         </cmp-field>
         <cmp-field >
            <description><![CDATA[Getter for CMP Field mapY]]></description>
            <field-name>mapY</field-name>
         </cmp-field>
         <primkey-field>id</primkey-field>

	  <!-- Write a file named ejb-finders-KnotenEJB.xml if you want to define extra finders. -->

      </entity>

     <!--
       To add entity beans that you have deployment descriptor info for, add
       a file to your XDoclet merge directory called entity-beans.xml that contains
       the <entity></entity> markup for those beans.
     -->

      <!-- Message Driven Beans -->
     <!--
       To add message driven beans that you have deployment descriptor info for, add
       a file to your XDoclet merge directory called message-driven-beans.xml that contains
       the <message-driven></message-driven> markup for those beans.
     -->

   </enterprise-beans>

   <!-- Relationships -->

   <!-- Assembly Descriptor -->
     <!--
       To specify your own assembly descriptor info here, add a file to your
       XDoclet merge directory called assembly-descriptor.xml that contains
       the <assembly-descriptor></assembly-descriptor> markup.
     -->

   <assembly-descriptor >
     <!--
       To specify additional security-role elements, add a file in the merge
       directory called ejb-security-roles.xml that contains them.
     -->

   <!-- method permissions -->
     <!--
       To specify additional method-permission elements, add a file in the merge
       directory called ejb-method-permissions.ent that contains them.
     -->

   <!-- transactions -->
     <!--
       To specify additional container-transaction elements, add a file in the merge
       directory called ejb-container-transactions.ent that contains them.
     -->

   <!-- finder transactions -->

   <!-- message destinations -->
     <!--
       To specify additional message-destination elements, add a file in the merge
       directory called ejb-message-destinations.ent that contains them.
     -->

   <!-- exclude list -->
     <!--
       To specify an exclude-list element, add a file in the merge directory
       called ejb-exclude-list.xml that contains it.
     -->
   </assembly-descriptor>

</ejb-jar>
 
Hallo,

ich weiß nicht, ob das dein Problem vollständig löst, aber was auf die Schnelle auffällt ist, dass die Bestandteile deines PrimaryKeys (int id und int nachbar) als private deklariert sind. Laut j2ee Spezifikation müssen die bei eigenen PrimaryKey-Klassen aber public sein.

Gruß
THMD
 
Hallo!

Schau mal hier:
Der Primärschlüssel der Entität Something setzt sich aus foo und bar zusammen:
Code:
 /*
  * Created on 23.11.2005@20:02:13
  *
  * TODO Add some Licence info
  */
 package de.tutorials.domain;
 
 import java.rmi.RemoteException;
 
 import javax.ejb.CreateException;
 import javax.ejb.EJBException;
 import javax.ejb.EntityBean;
 import javax.ejb.EntityContext;
 import javax.ejb.RemoveException;
 
 import de.tutorials.domain.pk.SomethingBeanPK;
 
 /**
  * @author Tom
  * @ejb.bean name="SomethingBean" display-name="SomethingBean"
  *		   description="Description for Person" type="CMP" cmp-version="2.x"
  *		   view-type="local"
  * @jboss.persistence create-table = "true" datasource = "java:/MySqlDS"
  *				    datasource-mapping = "mySQL" table-name = "SomethingExample"
  */
 public abstract class SomethingBean implements EntityBean {
 
 	/**
 	 * @ejb.create-method
 	 * @param foo
 	 * @param bar
 	 * @return
 	 * @throws CreateException
 	 */
 	public SomethingBeanPK ejbCreate(Integer foo, String bar) throws CreateException {
 		setFoo(foo);
 		setBar(bar);
 		return null;
 	}
 	
 	public void ejbPostCreate(Integer foo, String bar){
 	 
 	}
 	
 	
 
 	/**
 	 * @ejb.pk-field
 	 * @ejb.interface-method
 	 * @ejb.persistent-field
 	 * @return
 	 */
 	public abstract Integer getFoo();
 
 	public abstract void setFoo(Integer foo);
 
 	/**
 	 * @ejb.pk-field
 	 * @ejb.interface-method
 	 * @ejb.persistent-field
 	 * @return
 	 */
 	public abstract String getBar();
 
 	public abstract void setBar(String bar);
 
 	/**
 	 * @ejb.interface-method
 	 * @ejb.persistent-field
 	 * @return
 	 */
 	public abstract String getData();
 
 	/**
 	 * @ejb.interface-method
 	 * @return
 	 */
 	public abstract void setData(String data);
 
 	/*
 	 * (non-Javadoc)
 	 * 
 	 * @see javax.ejb.EntityBean#setEntityContext(javax.ejb.EntityContext)
 	 */
 	public void setEntityContext(EntityContext arg0) throws EJBException,
 			RemoteException {
 		// TODO Auto-generated method stub
 
 	}
 
 	/*
 	 * (non-Javadoc)
 	 * 
 	 * @see javax.ejb.EntityBean#unsetEntityContext()
 	 */
 	public void unsetEntityContext() throws EJBException, RemoteException {
 		// TODO Auto-generated method stub
 
 	}
 
 	/*
 	 * (non-Javadoc)
 	 * 
 	 * @see javax.ejb.EntityBean#ejbRemove()
 	 */
 	public void ejbRemove() throws RemoveException, EJBException,
 			RemoteException {
 		// TODO Auto-generated method stub
 
 	}
 
 	/*
 	 * (non-Javadoc)
 	 * 
 	 * @see javax.ejb.EntityBean#ejbActivate()
 	 */
 	public void ejbActivate() throws EJBException, RemoteException {
 
 	}
 
 	/*
 	 * (non-Javadoc)
 	 * 
 	 * @see javax.ejb.EntityBean#ejbPassivate()
 	 */
 	public void ejbPassivate() throws EJBException, RemoteException {
 
 	}
 
 	/*
 	 * (non-Javadoc)
 	 * 
 	 * @see javax.ejb.EntityBean#ejbLoad()
 	 */
 	public void ejbLoad() throws EJBException, RemoteException {
 
 	}
 
 	/*
 	 * (non-Javadoc)
 	 * 
 	 * @see javax.ejb.EntityBean#ejbStore()
 	 */
 	public void ejbStore() throws EJBException, RemoteException {
 
 	}
 }

... daraus baut mir XDoclet dann folgende PK-Klasse:
Code:
 /*
  * Generated by XDoclet - Do not edit!
  */
 package de.tutorials.domain.pk;
 
 /**
  * Primary key for SomethingBean.
  * @author Tom
  */
 public class SomethingBeanPK
    extends java.lang.Object
    implements java.io.Serializable
 {
 
    public java.lang.Integer foo;
    public java.lang.String bar;
 
    public SomethingBeanPK()
    {
    }
 
    public SomethingBeanPK( java.lang.Integer foo,java.lang.String bar )
    {
 	  this.foo = foo;
 	  this.bar = bar;
    }
 
    public java.lang.Integer getFoo()
    {
 	  return foo;
    }
    public java.lang.String getBar()
    {
 	  return bar;
    }
 
    public void setFoo(java.lang.Integer foo)
    {
 	  this.foo = foo;
    }
    public void setBar(java.lang.String bar)
    {
 	  this.bar = bar;
    }
 
    public int hashCode()
    {
 	  int _hashCode = 0;
 		 if (this.foo != null) _hashCode += this.foo.hashCode();
 		 if (this.bar != null) _hashCode += this.bar.hashCode();
 
 	  return _hashCode;
    }
 
    public boolean equals(Object obj)
    {
 	  if( !(obj instanceof de.tutorials.domain.pk.SomethingBeanPK) )
 		 return false;
 
 	  de.tutorials.domain.pk.SomethingBeanPK pk = (de.tutorials.domain.pk.SomethingBeanPK)obj;
 	  boolean eq = true;
 
 	  if( obj == null )
 	  {
 		 eq = false;
 	  }
 	  else
 	  {
 		 if( this.foo != null )
 		 {
 			eq = eq && this.foo.equals( pk.getFoo() );
 		 }
 		 else  // this.foo == null
 		 {
 			eq = eq && ( pk.getFoo() == null );
 		 }
 		 if( this.bar != null )
 		 {
 			eq = eq && this.bar.equals( pk.getBar() );
 		 }
 		 else  // this.bar == null
 		 {
 			eq = eq && ( pk.getBar() == null );
 		 }
 	  }
 
 	  return eq;
    }
 
    /** @return String representation of this pk in the form of [.field1.field2.field3]. */
    public String toString()
    {
 	  StringBuffer toStringValue = new StringBuffer("[.");
 		 toStringValue.append(this.foo).append('.');
 		 toStringValue.append(this.bar).append('.');
 	  toStringValue.append(']');
 	  return toStringValue.toString();
    }
 
 }

Siehe auch das Beispielprojekt im Anhang...

Btw. Ich hoffe du hast sehr gute Gründe noch EJB zu verwenden... heut zu tage gibt es bei weitem elegantere/einfachere/effektivere Alternativen zu EJB.

Gruss Tom
 

Anhänge

  • de.tutorials.anotherejbexample.z
    26,3 KB · Aufrufe: 44
Danke für die Antwort. Der Grund warum ich noch immer EJBs nutze ist mein Prof ana UNI, der das für das Projekt in diesem (7ten) Semester verlangt. Ich persönlich mag es au nich so.

Aber mal aus Interesse...was würdest zZ empfehlen für komplexe datenbank/user-lastige Webanwendungen ?
 
N'Abend,

Thomas Darimont hat gesagt.:
Btw. Ich hoffe du hast sehr gute Gründe noch EJB zu verwenden...
Ohje ich benutz noch EJB - jetzt fühl ich mich echt mies und ausgegrenzt? :-(
Oder was wären denn z.B. sehr gute Gründe? Nur damit ich mich vielleicht wieder besser fühlen kann... ;)

THMD
 
Hallo!

Ohje ich benutz noch EJB - jetzt fühl ich mich echt mies und ausgegrenzt? :-(
Oder was wären denn z.B. sehr gute Gründe? Nur damit ich mich vielleicht wieder besser fühlen kann... ;)
Gute Gründe für den Einsatz von EJB wären beispielsweise die Vorgaben des Kunden. Wenn der Kunde sagt dass man ein System mit EJB bauen MUSS hat man eben keine andere Wahl. Dies ist vor allem dann der Fall, wenn der Kunde schon viele mit EJB realisierte Anwendungen hat und Integrationsprobleme befürchtet (... und sich dann nicht davon abbringen lässt).

Aus technischer Sicht macht EJB vor allem dann Sinn, wenn das System eine hochgradig verteilte Anwendung sein soll.
Wenn dich die ganze Sache interessiert, würde ich dir empfehlen dir mal das Buch "J2EE Development without EJB" anzuschauen... Dort beschreibt Rod Johnson (einer der Väter des Springframeworks) auf ca. 600 Seiten, weshalb man sich mit Verwendung von EJB Technologie nur das Leben schwer macht, und dass es für viele EJB Probleme sehr viel einfachere und eleganter alternative Lösungmöglichkeiten gibt.
http://shop.tutorials.de/buch/0764558315/Expert_One_on_One_J2EE_Development_without_EJB.html

Gruss Tom
 

Neue Beiträge

Zurück