Finder methods + JBoss + Was expecting one of: "CONCAT" "SUBSTRING" ... "(" ... <STRI

cengizhdde

Mitglied
Hallo zusammen,

ich arbeite mit Container Managed Persistence-Beans in der Version 2.0 unter JBoss 4.0 auf Windows XP Prof. Beim Deployment auf den Server erhalte ich folgende Fehlermeldung:

2005-05-27 10:30:13,316 DEBUG [org.jboss.util.NestedThrowable] org.jboss.util.NestedThrowable.parentTraceEnabled=true
2005-05-27 10:30:13,316 DEBUG [org.jboss.util.NestedThrowable] org.jboss.util.NestedThrowable.nestedTraceEnabled=false
2005-05-27 10:30:13,316 DEBUG [org.jboss.util.NestedThrowable] org.jboss.util.NestedThrowable.detectDuplicateNesting=true
2005-05-27 10:30:13,316 ERROR [org.jboss.ejb.EntityContainer] Starting failed jboss.j2ee:jndiName=CmpL001PcDeEjb,service=EJB
org.jboss.deployment.DeploymentException: Error compiling EJB-QL statement 'SELECT OBJECT(a) FROM CmpL003PcTrSchema as a WHERE LENGTH(a.level003_pc_id) = ?1 AND a.level003_pc_id LIKE ?2'; - nested throwable: (org.jboss.ejb.plugins.cmp.ejbql.ParseException: Encountered "a.level003_pc_id" at line 1, column 61.
Was expecting one of:
"CONCAT" ...
"SUBSTRING" ...
"(" ...
<STRING_LITERAL> ...
<STRING_VALUED_PARAMETER> ...
<STRING_VALUED_PATH> ...
)
at org.jboss.ejb.plugins.cmp.jdbc.JDBCEJBQLQuery.<init>(JDBCEJBQLQuery.java:52)
at org.jboss.ejb.plugins.cmp.jdbc.JDBCCommandFactory.createEJBQLQuery(JDBCCommandFactory.java:60)
at org.jboss.ejb.plugins.cmp.jdbc.JDBCQueryManager.start(JDBCQueryManager.java:272)
at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.startStoreManager(JDBCStoreManager.java:490)
at org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.start(JDBCStoreManager.java:381)
at org.jboss.ejb.plugins.CMPPersistenceManager.start(CMPPersistenceManager.java:157)
at org.jboss.ejb.EntityContainer.startService(EntityContainer.java:340)
at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:272)
at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:222)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
...............
...............

Folgende Einträge wurden von mir vorgenommen:

In der Home-Schnittstelle:

public java.util.Collection findByRequirements(int length,java.lang.String flag)
throws javax.ejb.FinderException,java.rmi.RemoteException;

Im ejb-jar.xml-Deskriptor:

<query>
<query-method>
<method-name>findByRequirements</method-name>
<method-params>
<method-param>int</method-param>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<ejb-ql><![CDATA[SELECT OBJECT(a) FROM CmpL003PcDeSchema as a WHERE LENGTH(a.level003_pc_id) = ?1 AND a.level003_pc_id LIKE ?2]]></ejb-ql>
</query>

Soweit ich weiss gibt es in der Home-Schnittstelle mit der Übergabe von primitiven Datentypen (int) keine Probleme.

Eine mögliche Lösung die ich in den Foren gefunden habe ist die Implementierung von Declared-SQL statt der Query die ich im Deskriptor verwende.

Beispiel:

<declared-sql>
<select><alias>a</alias></select>
<where>WHERE LENGTH(a.level003_pc_id = {0}) AND a.level003_pc_id LIKE {1}</where>
<order></order>
</declared-sql>

Ich setze als Datenbank MySQL v4.0 ein.

Kann jemand helfen? Danke im Voraus.
 
sorry, habe vergessen zu schreiben, das die Declared-SQL-Methode nicht funktioniert hat. Beim Deployment kommt die Fehlermeldung, das kein Bezug zwischen der Methode und dem Deskriptor bestehen würde.
 
Re: Finder methods + JBoss + Was expecting one of: "CONCAT" "SUBSTRING" ... "(" ... <

Hallo!

Code:
SELECT OBJECT(a) FROM CmpL003PcTrSchema as a WHERE LENGTH(a.level003_pc_id) = ?1 AND a.level003_pc_id LIKE ?2

Ist a.level003_pc_id auch ein String kompatibler Typ?

Gruß Tom
 
Re: Finder methods + JBoss + Was expecting one of: "CONCAT" "SUBSTRING" ... "(" ... <

Hallo!

Also unter JBoss 3.2.7 funktioniert folgendes einwandfrei:

PersonBean -> Local CMP EntityBean
Code:
/*
 * Created on 27.05.2005@12:20:20 by Darimont
 *
 * TODO Licence info
 */
package de.tutorials.ejb.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;

/**
 * @author Darimont
 * 
 * TODO Explain me
 * @ejb.bean description="PersonBean"
 *           display-name="PersonBean"
 *           local-jndi-name="PersonHomeLocal"
 *           name="Person"
 *           primkey-field="id"
 *           type="CMP"
 *           view-type="local" cmp-version = "2.x" 
 * @ejb.value-object generatePKConstructor = "true"
 * 
 * @ejb.finder signature = "Person findPersonByName(java.lang.String name)"
 *             description = "Find Person by Name" query = "SELECT OBJECT(p) FROM Person AS p WHERE p.lastName=?1"
 * @ejb.finder signature = "Person findPersonByNameWithLen(java.lang.String name,int len)"
 *             description = "Find Person by Name" query = "SELECT OBJECT(p) FROM Person AS p WHERE p.lastName=?1 AND LENGTH(p.lastName)=?2"
 * 
 * 
 * @jboss.persistence create-table = "true" datasource = "java:/MySqlDS" datasource-mapping = "mySQL"  table-name = "Person"
 * @jboss.entity-command name = "mysql-get-generated-keys"
 * @jboss.unknown-pk auto-increment = "true" column-name = "id"
 */
public abstract class PersonBean implements EntityBean {

	/**
	 * @ejb.create-method view-type = "local"
	 * 
	 * @param id
	 * @return
	 * @throws CreateException
	 */
	public Integer ejbCreate() throws CreateException {
		return null;
	}
	
	public void ejbPostCreate() throws CreateException {}

	/**
	 * @ejb.interface-method
	 * @ejb.pk-field
	 * @ejb.persistence column-name = "id" 
	 * @return
	 */
	public abstract Integer getId();

	/**
	 * @ejb.interface-method 
	 * @return
	 */
	public abstract void setId(Integer id);

	/**
	 * @ejb.interface-method
	 * @ejb.persistence column-name = "lastname" 
	 * @return
	 */
	public abstract String getLastName();

	/**
	 * @ejb.interface-method 
	 * @return
	 */
	public abstract void setLastName(String lastName);

	public void ejbActivate() throws EJBException, RemoteException {
	}

	public void ejbLoad() throws EJBException, RemoteException {
	}

	public void ejbPassivate() throws EJBException, RemoteException {
	}

	public void ejbRemove() throws RemoveException, EJBException,
			RemoteException {
	}

	public void ejbStore() throws EJBException, RemoteException {
	}

	public void setEntityContext(EntityContext arg0) throws EJBException,
			RemoteException {
	}

	public void unsetEntityContext() throws EJBException, RemoteException {
	}

}

Hier das passende ejb-jar.xml:
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[PersonServiceBean]]></description>
         <display-name>PersonServiceBean</display-name>

         <ejb-name>PersonService</ejb-name>

         <home>de.tutorials.ejb.generated.PersonServiceHome</home>
         <remote>de.tutorials.ejb.generated.PersonService</remote>
         <ejb-class>de.tutorials.ejb.service.PersonServiceBean</ejb-class>
         <session-type>Stateless</session-type>
         <transaction-type>Container</transaction-type>

      </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[PersonBean]]></description>
         <display-name>PersonBean</display-name>

         <ejb-name>Person</ejb-name>

         <local-home>de.tutorials.ejb.generated.PersonLocalHome</local-home>
         <local>de.tutorials.ejb.generated.PersonLocal</local>

         <ejb-class>de.tutorials.ejb.domain.PersonBean</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>Person</abstract-schema-name>
         <cmp-field >
            <description><![CDATA[]]></description>
            <field-name>id</field-name>
         </cmp-field>
         <cmp-field >
            <description><![CDATA[]]></description>
            <field-name>lastName</field-name>
         </cmp-field>
         <primkey-field>id</primkey-field>

         <query>
            <description><![CDATA[Find Person by Name]]></description>
            <query-method>
               <method-name>findPersonByName</method-name>
               <method-params>
                  <method-param>java.lang.String</method-param>
               </method-params>
            </query-method>
            <ejb-ql><![CDATA[SELECT OBJECT(p) FROM Person AS p WHERE p.lastName=?1]]></ejb-ql>
         </query>
         <query>
            <description><![CDATA[Find Person by Name]]></description>
            <query-method>
               <method-name>findPersonByNameWithLen</method-name>
               <method-params>
                  <method-param>java.lang.String</method-param>
                  <method-param>int</method-param>
               </method-params>
            </query-method>
            <ejb-ql><![CDATA[SELECT OBJECT(p) FROM Person AS p WHERE p.lastName=?1 AND LENGTH(p.lastName)=?2]]></ejb-ql>
         </query>
	  <!-- Write a file named ejb-finders-PersonBean.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 -->
   <assembly-descriptor >
     <!--
       To add additional assembly descriptor info here, add a file to your
       XDoclet merge directory called assembly-descriptor.xml that contains
       the <assembly-descriptor></assembly-descriptor> markup.
     -->

   <!-- finder permissions -->

   <!-- finder permissions -->

   <!-- transactions -->

   <!-- finder transactions -->
   </assembly-descriptor>

</ejb-jar>

Gruß Tom
 
Hallo Tom,

danke für die schnelle Antwort. Ja, das Attribut level003_pc_id ist vom Typ java.lang.String.

Der Unterschied zu Deinem Quelltext liegt innnerhalb der Entity-Bean. Ich arbeite mit dem XDoclet-Klassengenerator und verwende Ant für das Deployment.

Sind in CMP v2.0 die Signatur von Finder-Methoden innerhalb der Entity Bean erforderlich? Falls ja, werden - kann ich mir denken - die Einträge in der die ejb-jar.xml-Datei überschrieben?

Soweit ich sehen konnte ist Deine ejb-jar.xml mit meiner identisch.

Danke und Gruss

Cengiz
 
Re: Finder methods + JBoss + Was expecting one of: "CONCAT" "SUBSTRING" ... "(" ... <

Hallo!

Der Unterschied zu Deinem Quelltext liegt innnerhalb der Entity-Bean. Ich arbeite mit dem XDoclet-Klassengenerator und verwende Ant für das Deployment.
Ich arbeite auch mit XDoclet... siehe @ejb.bla ;-)

Sind in CMP v2.0 die Signatur von Finder-Methoden innerhalb der Entity Bean erforderlich?
Innerhalb der EntityBean nicht ... finder-Methoden werden an den Home/LocalHome- Interfaces angegeben.
Über
* @ejb.finder signature = "Person findPersonByName(java.lang.String name)"
* description = "Find Person by Name" query = "SELECT OBJECT(p) FROM Person AS p WHERE p.lastName=?1"

generiere ich mit Xdoclet diese Methode am LocalHome:
Code:
   public de.tutorials.ejb.generated.PersonLocal findPersonByNameWithLen(java.lang.String name,int len)
      throws javax.ejb.FinderException;


Gruß Tom
 
Re: Finder methods + JBoss + Was expecting one of: "CONCAT" "SUBSTRING" ... "(" ... <

Hallo,

also meine Home-Schnittstelle der CMP sieht wie folgt aus:

public com.de.ibais.viuna.cmp.pc.CmpL002PcDe create(java.lang.Long id , java.sql.Timestamp lastModify , java.lang.String pc , java.lang.String valid , java.lang.String description)
throws javax.ejb.CreateException,java.rmi.RemoteException;

public java.util.Collection findAll()
throws javax.ejb.FinderException,java.rmi.RemoteException;

public java.util.Collection findByRequirements(int length,java.lang.String flag)
throws javax.ejb.FinderException,java.rmi.RemoteException;

public com.de.ibais.viuna.cmp.pc.CmpL002PcDe findByPrimaryKey(java.lang.Long pk)
throws javax.ejb.FinderException,java.rmi.RemoteException;

Die ejb-jar.xml kennst du. Hier nochmal der Auszug:

<query>
<query-method>
<method-name>findByRequirements</method-name>
<method-params>
<method-param>int</method-param>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<ejb-ql><![CDATA[SELECT OBJECT(a) FROM CmpL003PcDeSchema as a WHERE LENGTH(a.level003_pc_id) = ?1 AND a.level003_pc_id LIKE ?2]]></ejb-ql>
</query>

Soweit ich weiss sind keine weiteren Einstellungen erforderlich. Die Fehlermeldung besteht leider wie bisher.

Idee(n) ?

Gruss und schönes Wochenende.

Cengiz
 

Neue Beiträge

Zurück