Java & EJB3: How to correctly pass @Entity objects from Client to Server?

ejb, entity, jpa, rmi, serialization

Solution

My guess is it is related to the serialVersionUID you have defined, or the CORBA serializer you are using. Not sure if you can try regular RMI. Try also serializing/deserialing the object just on the client, does it work? Also try just on the server.

My guess is the class versions in your client and server are somehow different. This is most likely related to how JPA weaves the classes on the server. Try disabling weaving in your persistence.xml, does this resolve the issue?

If it does, then try using static weaving of the jar, so both the client and the server share the same jar.

What version of Glassfish and JDK are you using? We have similar tests that call remote session beans from clients in Glassfish, and they do not have any issues.

Problem

I'm currently trying to pass an @Entity object from a stand-alone client to the server enterprise application by calling a business method on a facade that was auto-generated by Netbeans (Session Beans for Entity classes Wizard). The @Entity class consists of two String fields. But when the object arrives on the server side, all fields are "null", although I correctly initialized the entity object correctly on the client side before calling the remote method of the facade which in turn should store the object to my MySQL database (in fact it's stored, but with those null references). There are no errors and everything works just fine except passing @Entity object from client to server. The reverse way works. I manually added a row in my table and call the remote business method find(Object id) of the facade in order to get the entry of the db back to the client. Marshalling works just fine in this direction. Basically it consists of 3 projects (classes attached on the bottom): - Enterprise-App/EJB: holds the implementation of the facade and JDBC connection to MySQL - Java Class-Library: holds the interfaces for the remote business methods and the entity-bean (this one is shared (referenced) by the server- and client side) - Java Application: builds InitialContext and executes the JNDI lookup to get the references to the remote business methods of the facade I face this problem now for two days and nobody has any clue how to solve. Internet search completely failed. Thus, any ideas are highly appreciated - Many thanks in advance! Any ideas highly appreciated. A1) EJB/Enterprise-App: Here's the abstract facade class (autogenerated by Netbeans): ``` public abstract class AbstractFacade<T> { private Class<T> entityClass; public AbstractFacade(Class<T> entityClass) { this.entityClass = entityClass; } protected abstract EntityManager getEntityManager(); public void create(T entity) { getEntityManager().persist(entity); } public void edit(T entity) { getEntityManager().merge(entity); } public void remove(T entity) { getEntityManager().remove(getEntityManager().merge(entity)); } public T find(Object id) { return getEntityManager().find(entityClass, id); } } ``` A2) EJB/Enterprise-App: the facade implementation (autogenerated by Netbeans): ``` @Stateless public class UserFacade extends AbstractFacade<User> implements UserFacadeRemote { @PersistenceContext(unitName = "LawSuiteEE-ejbPU") private EntityManager em; @Override protected EntityManager getEntityManager() { return em; } public UserFacade() { super(User.class); } } ``` B1) Shared Class-Library: Here's the entity class: ``` @Entity public class User implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private Long id; private String username; private String password; public User() { } public User(Long id) { this.id = id; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Integer getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } ``` B2) Shared Class-Library: the remote facade interface: ``` @Remote public interface UserFacadeRemote { void create(User user); void edit(User user); void remove(User user); User find(Object id); } ``` C) Client Java Application: ``` public class LawSuiteSE { private static UserFacadeRemote ctrlUser; public LawSuiteSE() { try { Properties props = new Properties(); props.put("org.omg.CORBA.ORBInitialHost", "192.168.1.6"); props.put("org.omg.CORBA.ORBInitialPort", "3700"); InitialContext ctx = new InitialContext(props); ctrlBenutzer = (BenutzerFacadeRemote)ctx.lookup("java:global/LawSuiteEE/LawSuiteEE-ejb/UserFacade!control.UserFacadeRemote"); User user1 = new User(); user1.setUsername("testusr"); user1.setPassword("testpwd"); ctrlUser.create(user1); User user2 = ctrlUser.find(1L); System.out.println("username: "+user2.getUsername()); System.out.println("password: "+user2.getPassword()); } catch (NamingException ex) { System.err.println(ex.getMessage()); } } public static void main(String[] args) { LawSuiteSE lsse = new LawSuiteSE(); } } ```

Original source

Related problems