【问题标题】:OpenEntityManagerInViewInterceptor analog for CLI application?CLI 应用程序的 OpenEntityManagerInViewInterceptor 模拟?
【发布时间】:2013-06-30 21:44:27
【问题描述】:

有没有类似OpenEntityManagerInViewInterceptor 的 CLI 应用程序?

我正在尝试在 CLI 应用程序中使用 Spring 的 CrudRepository 和由 Hibernate 4 支持的 JPA 数据源。

我的main 方法创建一个包含该方法的类的实例,并使用context.getBeanFactory().autowireBean(object); 注入服务。

用于获取数据的服务具有使用@Transactional 注释的方法。这些方法调用CrudRepository 的方法。

但是当我尝试在 CLI 应用程序中管理相关实体时收到org.hibernate.LazyInitializationException

是否有任何解决方法可以在 @Transactional 方法之外的 CLI 应用程序中进行延迟加载,例如用于 Web 应用程序的 OpenEntityManagerInViewInterceptor

看下面的sn-p:

public class test {

    @Autowired
    public UserService userService;

    public static void main(String[] args) {
        test test = new test();
        //injecting dependencies into test
        test.run();
    }

    private void run() {
        User user = userService.findById(42);
        System.out.println(user.getLogin()); //User was fetched successfully
        Address address = new Address("London");
        user.addAddress(address);//Exception in thread "main" java.lang.RuntimeException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection
    }
}

【问题讨论】:

    标签: java spring hibernate spring-data spring-data-jpa


    【解决方案1】:

    我会说 CLI 没有一个,因为在 MVC 模式中没有 View 的概念。但是我怀疑您的问题是由于无效的声明式事务管理。

    对于 CLI 应用程序,请确保您已正确设置数据源、EntityManagerFactory 和 declarative transaction managemeent

    一个好的做法是将您的业务/DAO 代码包含在使用@Service@Repository@Component 或其他适当的 spring 注释注释的服务/存储库类中,创建您自己的 ApplicationContext 并获取对您的服务的引用:

    // UserDAO.java ----------------------------------------
    @Repository
    public class UserDAO {
      @PersistenceContext private EntityManager em;
    
      @Transactional
      public User findById(long id) {
        // ...
      }
    }
    
    // UserService.java ----------------------------------------
    @Service
    public class UserService {
      @Autowired private UserDAO userDAO;
      // ...
    }
    
    // MainClass.java ----------------------------------------
    public class MainClass {
      public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/root-context.xml");
        UserService userService = context.getBean(UserService.class);
    
        // more code here..
    
        context.close();
      }
    }
    

    只要 bean 是由 Spring 容器创建的,自动装配和声明式事务仍然可以正常工作。

    【讨论】:

      猜你喜欢
      • 2013-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      相关资源
      最近更新 更多