Java& EJB3:如何正确地将@Entity对象从客户端传递到服务器?

时间:2012-04-17 12:28:48

标签: serialization jpa ejb entity rmi

我正在尝试通过调用由Netbeans(会话Bean实体类向导)自动生成的外观上的业务方法,将@Entity对象从独立客户端传递到服务器企业应用程序。 / p>

@Entity类由两个String字段组成。但是当对象到达服务器端时,所有字段都是“null”,尽管我在调用Facade的远程方法之前在客户端正确初始化了实体对象,而后者又将对象存储到我的MySQL数据库中(在事实上它是存储的,但是使用那些空引用)。没有错误,除了将@Entity对象从客户端传递到服务器之外,一切正常。

相反的方式有效。我在我的表中手动添加了一行并调用了Facade的远程业务方法find(Object id),以便将db的条目返回给客户端。编组在这方面工作得很好。

基本上它由3个项目组成(底部附有类):

  1. Enterprise-App / EJB:保存outlook的实现和与MySQL的JDBC连接
  2. Java Class-Library:保存远程业务方法和entity-bean的接口(这个接口由服务器端和客户端共享(引用))
  3. Java Application:构建InitialContext并执行JNDI查找以获取对Facade远程业务方法的引用
  4. 我现在面对这个问题已经两天了,没有人知道怎么解决。互联网搜索完全失败。因此,任何想法都受到高度赞赏 - 非常感谢提前!

    任何想法都受到高度赞赏。

    A1)EJB / Enterprise-App:这是抽象外观类(由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:Facade实现(由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)共享类库:这是实体类:

    @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)共享类库:远程外观接口:

    @Remote
    public interface UserFacadeRemote {
        void create(User user);
        void edit(User user);
        void remove(User user);
        User find(Object id);
    }
    

    C)客户端Java应用程序:

    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();
        }
    
    }
    

1 个答案:

答案 0 :(得分:6)

我的猜测是它与您定义的serialVersionUID或您正在使用的CORBA序列化程序有关。不确定您是否可以尝试常规RMI。尝试在客户端上对序列化/解除对象,它是否有效?也可以在服务器上试试。

我的猜测是你的客户端和服务器中的类版本有些不同。这很可能与JPA如何在服务器上编写类有关。尝试在persistence.xml中禁用编织,这是否可以解决问题?

如果是,请尝试使用jar的静态编织,因此客户端和服务器共享同一个jar。

您使用的是什么版本的Glassfish和JDK?我们有类似的测试,从Glassfish中的客户端调用远程会话bean,它们没有任何问题。