当前位置: 首页 > 面试题库 >

在控制台应用程序中将spring-data-jpa与hibernate一起使用时如何延迟加载

淳于升
2023-03-14
问题内容

我有一个小型控制台应用程序,并且将spring-data-jpa与hibernate一起使用。我真的不知道在独立控制台应用程序中使用spring-data-
jpa及其存储库时如何懒惰初始化集合。这是我的一些代码:

@Entity
public class User {
...
    @OneToMany(cascade=CascadeType.ALL)
    @JoinColumn(name="USER_ORDER_ID")
    private Set<Order> orders = new HashSet<Order>();
...
}

资料库:

public interface UserRepository extends PagingAndSortingRepository<User, Long> {

    public ArrayList<User> findByFirstNameIgnoreCase(String firstName);
}

服务展示:

@Service
@Repository
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;

public ArrayList<User> findByFirstNameIgnoreCase(String firstName) {
    ArrayList<User> users = new ArrayList<User>();
    users = userRepository.findByFirstNameIgnoreCase(firstName);
    return users;
}

我的主要方法:

...
user = userRepository.findByFirstNameIgnoreCase("john").get(0);
orders = user.getOrders();
for (Order order : orders) {
  LOGGER.info("getting orders: " + order.getId());
}

foreach循环获取异常:

EVERE:无法延迟初始化角色集合:com.aki.util.User.orders,未关闭任何会话或会话org.hibernate.LazyInitializationException:无法延迟初始化角色集合:

请注意,从带有某种OpenSessionInViewFilter的Web应用程序运行此程序时,我没有此问题。


问题答案:

一种解决方案是通过以下方式制作User.orders一个 热切的 收藏

@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Order> orders = new HashSet<Order>();

默认情况下,实体关联是延迟加载的。这意味着ordersSet实际上只是一个代理对象,除非您在其上调用方法,否则它不会被初始化。这很好,因为Order除非需要它们,否则不会加载关联的对象。但是,如果您尝试在运行的事务之外访问未初始化的集合,则可能会导致问题。

如果您知道在大多数情况下您将需要用户订单,那么使关联热切地获取是有意义的。否则,您将必须确保集合在事务内被初始化/加载。在OpenSessionInViewFilter你确定提到品牌,交易停留在请求处理过程中打开,这就是为什么你没有在YOUT的webapp这个问题。

如果必须让它延迟加载,请尝试使用Spring TransactionTemplate将代码包装在您的main方法中:

TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    @Override
    protected void doInTransactionWithoutResult(TransactionStatus status) {
    ...
    }
});


 类似资料:
  • 我有一个小的控制台应用程序,我正在使用spring-data-jpa和Hibernate。我真的搞不懂在一个独立的控制台应用程序中使用spring-data-jpa及其存储库时如何延迟初始化集合。下面是我的一些代码: 存储库: 服务影响:

  • 问题内容: 我倾向于将Hibernate与Spring框架结合使用,它具有声明式事务划分功能(例如@Transactional)。 众所周知,hibernate试图尽可能做到 非侵入性 和 透明性 ,但是事实证明,在使用关系时这 更具挑战性 。 我看到了许多具有不同透明度的设计方案。 使关系不延迟加载(例如, 这违反了整个延迟加载的想法。 使用初始化初始化集合 这意味着与DAO的耦合较高 尽管我们

  • 问题内容: 我有一个Person类: 与多对多的关系是懒惰的。 在我的控制器中 而PersonRepository只是此代码. 但是,在此控制器中,我实际上需要惰性数据。如何触发加载? 尝试访问它将会失败 无法延迟初始化角色集合:no.dusken.momus.model.Person.roles,无法初始化代理-没有会话 或其他例外情况,具体取决于我的尝试。 我的xml-description,

  • 问题内容: 我正在使用spring数据,我的DAO看起来像 在上面的代码中,注释行显示了我的意图。Spring Data是否可以提供内置功能来使用这种方法通过ASC / DESC按某列查找所有记录顺序? 问题答案: 上面的代码应该可以工作。我正在使用类似的东西: 它返回最高级别的10行。 重要提示: 由于有人告诉我很容易错过此答案的关键点,因此需要澄清一下:

  • 我正在做一个项目,使用Spring框架(Spring MVC,JDBC等)项目不是很大,使用Jetty servlet容器,PostgreSQL数据库与标准DAO类(sql请求)。我需要将Spring Boot和Hibernate/Spring JPA与存储库一起使用,而不是SQL查询。我发现有几种状态描述了向spring Boot的迁移:https://www.baeldung.com/spri

  • 好的,对于前面提到的技术,这是一个非常奇怪的行为,我有一个控制器,它调用一个服务,这调用一个dao。传递给持久化的实体有一个带有注释的字段,当我为dao或服务运行测试并插入重复值时,会抛出异常这是正常的,是预期的行为。但是,当我运行web应用程序时,异常会在服务完成执行后抛出。在执行dao时不会。因此,这迫使我在控制器中捕获异常,而不是在服务中。 控制器启动 服务//继续 DAO//继续(但是此时