【问题标题】:Service layer and dao layer in java ee EJBsjava ee EJB中的服务层和dao层
【发布时间】:2014-08-15 12:39:16
【问题描述】:

问题:任何人都可以在 Java EE 和 EJB 的上下文中展示具有两种不同方法的特定 DAO 类(或多个)。以及一个在一个事务边界中调用这两种方法并进行回滚的服务类?

我有一个 EJB,但我想将它用作服务层,就像在 spring @Transactional 方法中一样。

1) 这是个好主意吗?

2) 如何在一种方法中的一个“事务”中调用多个 dao 方法?我想我必须对 transaction.begin() 和 .提交()?任何人都可以显示一个代码示例吗?

一些主要优点是:

a- 所有小的不可变 DAO 事务都将在建立的单个数据库连接中“一次性”提交(single transactional boundries

b- 如果说我在服务器中有 4 个 dao 调用,而第三个调用失败,因为它是一个事务边界,我可以做 roll backs

c- 我的immutable DAO methods 在许多其他地方将是re-usable

Java EE 示例:

import com.....entities.Users;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

@Stateless
public class UsersBean {

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")

    public Users sayHello() {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("CommunityPU");
        EntityManager em = emf.createEntityManager();
        Users user =  em.find(Users.class, 1);
        em.close();
        emf.close();
        return user;
    }

}

对比春天:

@Controller
class MyControllerClass {

      @RequestMapping...
      method(){
         ServiceCall()...
      //put something to modelAndView object here and redirect to jsp page.
      return "home"; // this will redirect data to home.jsp

      }
}

//Service class /////////

@Service
class MyServiceClass{
      @Transactional
      SomeServiceMethod(){ 
        DaoMethod(); 
        SomeMoreDaoMethods();
      }

}

//Dao class ////////

@Autowired
EntityManager em;

@Repository
class MyDaoClass{
   DaoMethdon(){em.find(...)}

}

/view/myjsps.jsp  path to view directory set in spring.xml

编辑 - 1(交叉问题以进一步澄清答案)


1) DAO 本身会是EJB 吗?或 EJBs 是严格的 service layers 调用其他 immutable dao methods(位于 dao 类中)。

2) 我们不会在EJBs 中使用entitymanager,而是在Daos 中使用。正确的?

3) 使用@Transactional 怎么样(直到Java EE 7 只有EJB,其中事务性和@Transactional 注释不存在。)或@TransactionAttribute

4) 如果我们使用非@stateless 会怎样。那么它不会在一个事务边界中管理 daos 而不使用回滚?

RND 链接:

https://stackoverflow.com/a/17840851

http://docs.oracle.com/javaee/5/tutorial/doc/bncij.html

【问题讨论】:

    标签: spring jakarta-ee spring-mvc java-ee-6 java-ee-7


    【解决方案1】:

    是个好主意吗?

    是的。基本上,这就是 EJB 的用途。

    如何在一个方法中的一个“事务”中调用多个 dao 方法?

    你就去做吧:

     @Stateless
     public class MyService {
    
         @Inject
         private FirstDao firstDao;
    
         @Inject
         private SecondDao secondDao;
    
         // stateless EJBs are transactional by defaults.
         public void doStuff() {
             firstDao.doSomething();
             secondDao.doSomethingElse();
         }
    }
    

    默认情况下,EJB 是事务性的。您不需要以编程方式启动和提交事务。容器会为您执行此操作:如果 2 个 DAO 调用中的任何一个引发运行时异常,则事务将回滚。否则,它将提交。

    还请注意,您的服务 EJB 不应使用实体管理器。这就是 DAO 的用途:处理持久性。所以 DAO 应该是使用实体管理器的那个:

    public class FirstDao {
        @PersistenceContext
        private EntityManager em;
    
        ...
    }
    

    关于你最后的问题:

    1. DAO 本身可以是 EJB,但这不是必需的,因为事务通常由服务层划分。
    2. 我已经回答过了。当然 Data 访问对象是必须使用 EntityManager 的对象,因为它们的工作是处理持久性,而 EntityManager 用于访问数据库。
    3. 按照您想要的方式进行操作。重要的是您的服务应该是事务性的,无论您以何种方式使它们具有事务性。引入了事务性以消除对 EJB 的需求并具有事务性 CDI bean。如果你喜欢这样,那很好。

    小提示:不可变方法没有意义。某物(如对象)在其状态永不改变时是不可变的。方法没有状态。

    【讨论】:

    • +1 谢谢,我得到你的观点超过 90%。请参阅编辑 -1 了解我的交叉问题。
    • 肯定假设我总是使用 EJB,所以第 3 点 @Traansactional 在这里无效?我也加了4个。最后,我所说的不可变是指那些不能进一步分解的方法/动作。例如getUserById(id){return em.find(user.class, id);}
    • 你真的应该阅读答案。正如我在回答中所说的那样:默认情况下 EJB 是事务性的。我还说过:引入事务是为了消除对 EJB 的需求并拥有事务 CDI bean。你的第4点没有意义。如果您不使用@Stateless,那么您将不再定义 EJB。
    • 我阅读了答案,这是一个很好的答案。对于第 4 点)还有其他类型的 EJB。 @Stateless @Statefull , singleton
    • 它们都是 EJB。我的回答是:默认情况下 EJB 是事务性的。基本上每个 EJB 教程(和规范)都涵盖了这一点。读一读。
    猜你喜欢
    • 2013-07-01
    • 2017-06-07
    • 2013-05-16
    • 2013-05-27
    • 2012-11-26
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    相关资源
    最近更新 更多