【问题标题】:Java & EJB3: How to correctly pass @Entity objects from Client to Server?Java & EJB3:如何正确地将 @Entity 对象从客户端传递到服务器?
【发布时间】:2012-04-28 19:05:31
【问题描述】:

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

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

反之亦然。我在表中手动添加了一行,并调用了外观的远程业务方法 find(Object id),以便将 db 的条目返回给客户端。编组在这个方向上工作得很好。

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

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

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

高度赞赏的任何想法。

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:外观实现(由 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();
    }

}

【问题讨论】:

  • 嗨,barsju - 我在初始消息中发布了实体代码作为编辑...我真的很沮丧。我花了整整一周的时间来正确设置 GlassFish 服务器以便与 ACC 进行远程通信,现在这个问题又过了 2 天 :-( 我在 Internet 上找不到任何信息..
  • 很奇怪,你能把一个对象从服务器序列化到客户端吗?如果删除 serialVersionUID 会怎样?
  • 会话 bean 代码呢?实体是否保留在数据库中? BTW AFAIK MySql 不支持 SEQUENCE 生成策略。见stackoverflow.com/questions/5015766/…
  • 嗨 waclaw - 我的示例中的会话 bean 代码是使用 @Stateless 注释的 UserFacade 类。是的,实体保存在数据库中,但用户名和密码字段的值为“空”。好的,感谢有关 SEQUENCE 策略的提示,我暂时切换到 AUTO。还有什么想法吗?

标签: serialization jpa ejb entity rmi


【解决方案1】:

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

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

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

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

【讨论】:

  • 嗨詹姆斯 - 在persistence.xml中禁用编织完成了工作!非常非常感谢你 !我在 Ubuntu 11.10 和 JDK 1.6.0_30 上使用 GlassFish 3.1.2。那么,我该如何使用静态编织呢?
  • 这里是静态编织的 eclipse-link:wiki.eclipse.org/EclipseLink/UserGuide/JPA/…
  • 您是否尝试删除 serialVersionUID 并保持启用编织?对结果感兴趣。
  • @James:我在传递 entityDetail 列表时遇到了类似的问题。我正在使用 Glassfish v2.1 和 JDK 1.6。但是 Glassfish v3.1.2 不会出现问题!由于某些原因,我无法切换到更新的 glassfish。你能给我一些建议吗?谢谢
猜你喜欢
  • 2015-05-10
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多