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

sal*_*inx 2 serialization entity ejb jpa rmi

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

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

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

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

  1. Enterprise-App/EJB:包含与MySQL的Facade和JDBC连接的实现
  2. Java类库:保存远程业务方法和实体bean的接口(这个接口由服务器端和客户端共享(引用))
  3. Java应用程序:构建InitialContext并执行JNDI查找以获取对Facade的远程业务方法的引用

我现在面对这个问题已经两天了,没有人知道如何解决.互联网搜索完全失败.因此,任何想法都受到高度赞赏 - 非常感谢提前!

任何想法高度赞赏.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

}
Run Code Online (Sandbox Code Playgroud)

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

}
Run Code Online (Sandbox Code Playgroud)

B2)共享类库:远程外观接口:

@Remote
public interface UserFacadeRemote {
    void create(User user);
    void edit(User user);
    void remove(User user);
    User find(Object id);
}
Run Code Online (Sandbox Code Playgroud)

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

}
Run Code Online (Sandbox Code Playgroud)

Jam*_*mes 6

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

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

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

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