Hi,
I am developing an application that has three tiers.
From in to out:
The entities,
package entity;
import java.io.Serializable;
import javax.persistence.*;
import static javax.persistence.CascadeType.*;
import java.util.Collection;
import java.util.ArrayList;
/**
*
* @author NetbeansUser
*/
@Entity
public class Customer implements Serializable {
private int id;
private String name;
private Collection<Order> orders = new ArrayList<Order>();
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(cascade=ALL, mappedBy="customer")
public Collection<Order> getOrders() {
return orders;
}
public void setOrders(Collection<Order> newValue) {
this.orders = newValue;
}
@Override
public int hashCode() {
int hash = 0;
hash += (int) id;
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Customer)) {
return false;
}
Customer other = (Customer) object;
if (this.id != other.id) {
return false;
}
return true;
}
@Override
public String toString() {
return "entity.Customer[id=" + id + "]";
}
}
---------------------------------------------------------------------
package entity;
import javax.persistence.*;
/**
*
* @author NetbeansUser
*/
@Entity
@Table(name="ORDER_TABLE")
public class Order {
private int id;
private String address;
private Customer customer;
@Id
@Column(name="ORDER_ID")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="SHIPPING_ADDRESS")
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@ManyToOne()
@JoinColumn(name="CUSTOMER_ID")
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
==============================================
The facade stateless session bean
package ejb;
import javax.ejb.Remote;
import entity.Customer;
/**
*
* @author NetbeansUser
*/
@Remote
public interface Test {
// Insert Customer and Orders
public String testInsert();
// Verify that all are inserted
public String verifyInsert();
// Remove Customer and Orders
public String testDelete(int id);
// Verify that all are removed
public String verifyDelete();
// Get a detached instance of a Customer
public int findCustomer(String name);
public Customer findCustomer(int id);
}
-------------------------------------------------------------------------
package ejb;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.Collection;
import java.util.List;
import entity.*;
/**
*
* @author NetbeansUser
*/
@Stateless(name="ejb/Test")
public class TestBean implements Test {
// Add business logic below. (Right-click in editor and choose
// "Insert Code > Add Business Method" or "Web Service > Add Operation")
@PersistenceContext(unitName="pu1")
private EntityManager em;
public String testInsert() {
// Create new customer
Customer customer0 = new Customer();
customer0.setId(1);
customer0.setName("Joe Smith");
// Persist the customer
em.persist(customer0);
// Create 2 orders
Order order1 = new Order();
order1.setId(100);
order1.setAddress("123 Main St. Anytown, USA");
Order order2 = new Order();
order2.setId(200);
order2.setAddress("567 1st St. Random City, USA");
// Associate orders with the customer. The association
// must be set on both sides of the relationship: on the
// customer side for the orders to be persisted when
// transaction commits, and on the order side because it
// is the owning side.
customer0.getOrders().add(order1);
order1.setCustomer(customer0);
customer0.getOrders().add(order2);
order2.setCustomer(customer0);
return "OK";
}
public String verifyInsert() {
int id = findCustomer("Joe Smith");
Query q = em.createQuery("select c from Customer c where c.id = :id");
q.setParameter("name", id);
Customer c = (Customer)q.getSingleResult();
Collection<Order> orders = c.getOrders();
if (orders == null || orders.size() != 2) {
throw new RuntimeException("Unexpected number of orders: "
+ ((orders == null)? "null" : "" + orders.size()));
}
return "OK";
}
public String testDelete(int id) {
Customer c = findCustomer(id);
// Merge the customer to the new persistence context
Customer c0 = em.merge(c);
// Delete all records.
em.remove(c0);
return "OK";
}
public String verifyDelete() {
Query q = em.createQuery("select c from Customer c");
List results = q.getResultList();
if (results == null || results.size() != 0) {
throw new RuntimeException("Unexpected number of customers after delete");
}
q = em.createQuery("select o from Order o");
results = q.getResultList();
if (results == null || results.size() != 0) {
throw new RuntimeException("Unexpected number of orders after delete");
}
return "OK";
}
public int findCustomer(String name) {
Query q = em.createQuery("select c from Customer c where c.name = :name");
q.setParameter("name", name);
Customer c = (Customer)q.getSingleResult();
return c.getId();
}
public Customer findCustomer(int id){
Query q = em.createQuery("select c from Customer c where c.id = :id");
q.setParameter("id", id);
return (Customer)q.getSingleResult();
}
}
===========================================================================
And the standalone app client,
package client;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.*;
import ejb.Test;
import javax.naming.InitialContext;
import javax.naming.NamingException;
/**
* @author NetbeansUser
*/
public class AppClient {
@EJB(name="ejb/Test")
private static Test sb;
public AppClient() throws NamingException {
InitialContext ic = new InitialContext();
sb = (Test) ic.lookup("TestBean");
}
public static void main(String[] args) {
try {
AppClient test = new AppClient();
test.runTest();
} catch (NamingException ex) {
Logger.getLogger(AppClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void runTest() {
// Persist all entities
System.out.println("Inserting Customer and Orders... " + sb.testInsert());
// Test query and navigation
System.out.println("Verifying that all are inserted... " + sb.verifyInsert());
// Get a detached instance
int id = sb.findCustomer("Joe Smith");
// Remove all entities
System.out.println("Removing all... " + sb.testDelete(id));
// Query the results
System.out.println("Verifying that all are removed... " + sb.verifyDelete());
}
}
My client only knows the facade session tier.
But when I run it I get a NameNotFoundException. This is the stacktrace,
19-feb-2009 16:36:56 client.AppClient main
GRAVE: null
javax.naming.NameNotFoundException: TestBean not found
at com.sun.enterprise.naming.TransientContext.doLookup(TransientContext.java:216)
at com.sun.enterprise.naming.TransientContext.lookup(TransientContext.java:188)
at com.sun.enterprise.naming.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:74)
at com.sun.enterprise.naming.RemoteSerialContextProviderImpl.lookup(RemoteSerialContextProviderImpl.java:129)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:154)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:687)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:227)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1846)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1706)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:1088)
at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:223)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:806)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:563)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2567)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:555)
I use a sun-application-client.xml descriptor in my app client,
<sun-application-client>
<ejb-ref>
<ejb-ref-name>ejb/Test</ejb-ref-name>
<jndi-name>TestBean</jndi-name>
</ejb-ref>
</sun-application-client>
But the server log (glassfish v2ur2) says,
[#|2009-02-19T16:36:44.317+0100|SEVERE|sun-appserver9.1|javax.enterprise.system.tools.deployment|_ThreadID=31;_ThreadName=Thread-2253;_RequestID=c2a4c0d6-580c-41f5-9346-4bc114466417;|Class [ Lejb/Test; ] not found. Error while loading [ class client.AppClient ]|#]
[#|2009-02-19T16:36:44.317+0100|WARNING|sun-appserver9.1|javax.enterprise.system.tools.deployment|_ThreadID=31;_ThreadName=Thread-2253;_RequestID=c2a4c0d6-580c-41f5-9346-4bc114466417;|Error in annotation processing: java.lang.NoClassDefFoundError: Lejb/Test;|#]
[#|2009-02-19T16:36:44.317+0100|WARNING|sun-appserver9.1|javax.enterprise.system.tools.deployment|_ThreadID=31;_ThreadName=Thread-2253;_RequestID=c2a4c0d6-580c-41f5-9346-4bc114466417;|This application client [C:\glassfish-v2ur2\domains\domain1\applications\j2ee-modules\application] has no ejb reference by the name of [ejb/Test]|#]
[#|2009-02-19T16:36:44.317+0100|SEVERE|sun-appserver9.1|javax.enterprise.system.tools.deployment|_ThreadID=31;_ThreadName=Thread-2253;ejb-ref;ejb/Test;_RequestID=c2a4c0d6-580c-41f5-9346-4bc114466417;|"DPL8006: error while getting the descriptor: from ejb-ref to ejb/Test"|#]
And I do not know what is going wrong.
Any idea?
Thanking in advance,
Jose Alvarez de Lara