设计通用 CRUD 会话 Bean

2023-12-03

这个问题已经在这里被问过一次简单 CRUD 的 EJB 3 会话 Bean 设计,我只是想就这个设计提出更深入的问题。我已经尝试在原始帖子中提出问题,但是,我没有看到任何回复,所以我决定创建新帖子。所以实现通用CRUD会话bean的Pascal解决方案如下

public interface GenericCrudService {
    public <T> T create(T t);
    public <T> T find(Class<T> type, Object id);
    public <T> void delete(T t);
    public <T> T update(T t);
    public List findWithNamedQuery(String queryName);
    public List findWithNamedQuery(String queryName, int resultLimit);
    public List findWithNamedQuery(String namedQueryName, 
                                   Map<String, Object> parameters);
    public List findWithNamedQuery(String namedQueryName, 
                                   Map<String, Object> parameters,
                                   int resultLimit);
    public <T> List<T> findWithNativeQuery(String sql, Class<T> type);
}

AND

@Stateless
@Remote(GenericCrudService.class)
@TransactionAttribute(TransactionAttributeType.MANDATORY)
public class GenericCrudServiceBean implements GenericCrudService {
    @PersistenceContext
    private EntityManager em;

    @Override
    public <T> T create(T t) {
        em.persist(t);
        return t;
    }

    @Override
    public <T> T find(Class<T> type, Object id) {
        return em.find(type, id);
    }

    @Override
    public <T> void delete(T t) {
        t = em.merge(t);
        em.remove(t);
    }

    @Override
    public <T> T update(T t) {
        return em.merge(t);
    }

    @Override
    public List findWithNamedQuery(String queryName) {
        return em.createNamedQuery(queryName).getResultList();
    }

    @Override
    public List findWithNamedQuery(String queryName, int resultLimit) {
        return em.createNamedQuery(queryName).setMaxResults(resultLimit)
                .getResultList();
    }

    @Override
    public List findWithNamedQuery(String namedQueryName,
                                   Map<String, Object> parameters) {
        return findWithNamedQuery(namedQueryName, parameters, 0);          
    }

    @Override
    public List findWithNamedQuery(String namedQueryName,
                                   Map<String, Object> parameters,
                                   int resultLimit) {
        Query query = this.em.createNamedQuery(namedQueryName);
        if(resultLimit > 0) {
            query.setMaxResults(resultLimit);            
        }
        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
            query.setParameter(entry.getKey(), entry.getValue());
        }
        return query.getResultList();
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T>  List<T> findWithNativeQuery(String sql, Class<T> type) {
        return em.createNativeQuery(sql, type).getResultList();
    }
}

问题:

1)当我尝试在托管 bean 中引用此 EJB bean 时,我必须这样做

@EJB
private GenericCrudService myEJB;

代替

@EJB
private GenericCrudServiceBean myEJB;

这对我来说没什么意义,因为GenericCrudService只是一个接口,GenericCrudServiceBean是无状态 Bean

当我这样做时我得到这个异常GenericCrudServiceBean,

Caused by: javax.naming.NamingException: Lookup failed for 'java:comp/env/com.bridgeye.web.Profile/myEJB' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=com.bridgeye.web.Profile/myEJB,Remote 3.x interface =com.bridgeye.ejb.GenericCRUDServiceBean,ejb-link=null,lookup=,mappedName=,jndi-name=com.bridgeye.ejb.GenericCRUDServiceBean,refType=Session' .  Actual (possibly internal) Remote JNDI name used for lookup is 'com.bridgeye.ejb.GenericCRUDServiceBean#com.bridgeye.ejb.GenericCRUDServiceBean' [Root exception is javax.naming.NamingException: Lookup failed for 'com.bridgeye.ejb.GenericCRUDServiceBean#com.bridgeye.ejb.GenericCRUDServiceBean' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: com.bridgeye.ejb.GenericCRUDServiceBean#com.bridgeye.ejb.GenericCRUDServiceBean not found]]]
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:597)

2)javax.rmi.Remote和javax.ejb.Remote有什么不同?如果我取出注释Remote,我的EJB是否变成本地的,或者我必须用注释Local指定

3)在我的托管bean中,我做了一个简单的myEJB.find(User.class, id),但如果我有@TransactionAttribute(TransactionAttributeType.MANDATORY),然后我遇到异常,如果我拿出来它工作正常TransactionAttribute陈述。知道为什么吗?


  1. EJB 容器实际上将创建一个基于代理的接口实现,该接口包装您的 bean 并添加事务和安全检查等内容。然后将该代理注入到带注释的字段中,这就是它需要具有接口类型的原因。我认为在EJB 3.1中,你可以省略接口而只有一个bean类,容器将创建一个子类来实现它的魔力。
  2. javax.ejb.Remote是一个 EJB 3.0 注释,而java.rmi.Remote是 EJB 存在之前的简单接口。没有javax.rmi.Remote。你是对的,如果你不使用Remote注解,那么默认情况下 EJB 将被认为只有一个本地接口。
  3. 来自 API 文档TransactionAttributeType.MANDATORY:

    如果客户端调用企业 bean 的方法,而客户端是 与事务上下文相关联, 容器调用企业 客户端的bean方法 交易上下文。

    如果没有现有交易, 抛出异常。

    您可能想使用TransactionAttributeType.REQUIRED,如果不存在,它会自动启动事务,并且如果您使用不带参数的注释,它也是默认值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计通用 CRUD 会话 Bean 的相关文章

随机推荐

  • 如何在 swift 中将 .caf 音频文件转换为 .mp4 文件

    我正在使用设备麦克风录制音频AVAudioRecorder返回文件在 caf该格式只能在 Apple 设备上播放 而不能在 Android 设备上播放 由于苹果不支持 mp3文件 所以我想将其转换为 mp4上传到服务器之前格式化 是 mp4
  • Java 库/api 将语言代码转换为语言名称

    是否有一个 Java 库 api 给定 iso 语言代码 返回相应的语言名称 例如 zh cn 应返回中文 en 应返回英文等 Java Locale 类可以做到这一点 new Locale zh cn getDisplayName gt
  • HTTPClient-java.net.SocketException:抛出未连接的套接字未实现

    我正在使用 HTTPClient 4 0 连接远程服务器并使用 HTTPS 传输文件 当我尝试连接时 出现异常 java net SocketException 未实现未连接的套接字 请查看堆栈跟踪 java net SocketExcep
  • 无法通过 SSH 连接到 Google Cloud

    我安装了谷歌云SDK 我认为 Web UI 创建了一个新实例 我对 SSH 不太了解 我按照此处描述的步骤进行操作 https cloud google com compute docs instances sshkeys 我有 Windo
  • 如何在 Alpine 上安装 matplotlib

    尝试在 alpine docker 映像上安装 matplotlib 我收到一堆丑陋的消息 我是否缺少一些需要手动安装的额外先决条件 这是泊坞窗文件 FROM openjdk 8 jre alpine RUN apk update RUN
  • React Native:如何检测设备锁定/解锁事件?

    Concept 我的应用程序需要记录手机上的用户活动 活动包含前景 背景 杀死 锁定和解锁 我做了什么 我能够使用记录应用程序的前台 后台和终止状态应用程序状态库 要求 我需要对设备锁定 解锁状态执行操作 不幸的是 我无法侦听上述库中的设备
  • Zend 框架 get Request()->get Query() 不会在本地主机上带来查询字符串

    我有以下代码 它在实时站点上运行良好 但在本地主机上则不然 status this gt getRequest gt getQuery status 我有一个像这样的网址 http localhost 888 questions ask s
  • Null 传递给需要非空参数的被调用者

    我多年来一直使用它来将 CIImage 转换为 NSData NSData data imageRep representationUsingType NSPNGFileType properties nil 现在在 El Capitan
  • 检查是否选中基于工作表的复选框

    我正在尝试使用 IF 子句来确定是否选中了名为 Check Box 1 的复选框 我当前的代码 Sub Button167 Click If ActiveSheet Shapes Check Box 1 True Then Range Y1
  • 为您的应用程序启用网格/集群的最佳 Java 库是什么? [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 这是在服务器集群上运行应用程序的能力 旨在分配负载并提供额外的冗余 我看过一个演示GridGain我对此印象非常深刻 还知道其他人吗 有几个 红陶 开源 基于 Mozilla 公共许
  • 使用工作 numpy 创建 conda env 时遇到问题:“ImportError:无法导入名称 scalarmath”

    我想创建一个 conda env 比如 B 它有一个可用的 numpy 模块 我有一个工作的 miniconda 安装和另一个具有工作 numpy 的 conda env 比如 A 但无论我尝试什么方法 我都无法获得另一个具有工作 nump
  • android-maven-plugin 和资源过滤

    我是 Maven 的新手 并尝试配置它以使用 android maven plugin 构建我的 android 项目 我在资产目录中有一个 application properties 文件 其中包含不同的应用程序设置 我想从我的 pom
  • Spring OpenSessionInViewInterceptor 不起作用

    在渲染视图时 我遇到了休眠和延迟加载的 臭名昭著 问题 正如许多人所说 唯一的两个解决方案是 使方法具有事务性 这并不总是可取的 使用 OpenSessionInViewInterceptor IMO 后者更可取 无论如何 我不确定这个拦截
  • 截断可能包含或不包含 HTML 元素的段落文本的最快方法是什么?

    我需要截断可能包含或不包含 HTML 标签的段落文本 我正在寻找最有效的方法来使用直接 jQuery 或普通 javascript 来完成此操作 您可以在这里看到问题 http jsfiddle net 4BzpY 3 var text T
  • glm::lookAt 当 z <= 0 时垂直相机翻转

    我正在开发 FPS 风格的相机 以使用 OpenGL 在 3D 场景中飞行 我使用 GLM 进行数学计算 并使用鼠标移动在 x 轴和 y 轴上使用 glm rotate 计算方向向量 我有一个静态向上矢量 因为我可以在水平轴上扫射 并且实际
  • 如何仅在我的视图(及其 ngFors 等)更改后才执行代码?

    我正在尝试对充满图像的页面实施 MagnificPopup 解决方案 因为它们是通过 ngFor 渲染的 所以初始化弹出功能的代码在图像渲染之前运行 有没有办法仅在视图完成渲染 或者更好的是 视图内容已更改 时运行代码 我见过在组件的 In
  • 将中间输出分配给临时变量作为 dplyr 管道的一部分

    问 在 R dplyr 管道中 如何将一些中间输出分配给临时变量以便在管道中进一步使用 我下面的方法有效 但它分配到全局框架中 这是不可取的 一定有更好的方法 对吧 我认为涉及注释行的方法会得到预期的结果 没有骰子 很困惑为什么这不起作用
  • 如何使用 fmdb 作为登录页面?

    我有一个登录页面 其中有 2 个用于用户名和密码的文本字段以及一些按钮 我想知道如何使用 fmdb 检查我的数据库中是否存在用户名 密码组合 我还有另一个用于用户注册页面的视图控制器 有 4 个用于用户名 密码 电子邮件 联系电话的文本字段
  • 比较数字进行排序然后得到中值

    使用按位或比较运算符对五个整数进行排序可以通过以下方式实现 首先获取最大的数字 然后获取第二大的数字 然后获取第三大的数字 依此类推 这是我获取最高数字的代码 include
  • 设计通用 CRUD 会话 Bean

    这个问题已经在这里被问过一次简单 CRUD 的 EJB 3 会话 Bean 设计 我只是想就这个设计提出更深入的问题 我已经尝试在原始帖子中提出问题 但是 我没有看到任何回复 所以我决定创建新帖子 所以实现通用CRUD会话bean的Pasc