问题描述
我有一个带有嵌入式Derby的SpringBootApp;工作正常。当我实现CommandLineRunner或@postconstruct时,出现上述错误
“ org.hibernate.LazyInitializationException无法延迟初始化 角色集合:...-无法初始化代理-没有会话”。
在应用程序实际运行之前但加载了applications.properties文件之后,如何与Hibernate创建会话?另外,SprinBoot在其他地方正在采取哪些措施来防止正常运行中出现此错误?
@Component
@Transactional
public class DatabaseTesting01 {
private static Logger logger = LoggerFactory.getLogger(DatabaseTesting01.class);
@Autowired
EDITypeService ediTypeService;
@Autowired
vendorService vendorService;
@Autowired
SubscriberService subscriberService;
@postconstruct
public void init(){
vendor v = vendorService.findOneByShortName("UNFI");
logger.debug("vendor:UNFI"+v.toString());
}
}
更新 这是有效的。HTH。
@Component
@Service("database01")
public class Database01 {
private static Logger logger = LoggerFactory.getLogger(Database01.class);
@Autowired
@Qualifier("transactionManager")
protected PlatformTransactionManager txManager;
@Autowired vendorService vendorService;
@postconstruct
private void init(){
TransactionTemplate tmpl = new TransactionTemplate(txManager);
tmpl.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
vendorService.deleteall();
}
});
}
}
解决方法
@Transactional
对类所做的唯一一件事就是将事务功能(创建代理等)应用于所有公共方法。因此,您不应该依赖诸如@PostConstruct
之类的初始化代码。
这是适当的spring reference
在代理模式(默认)下,仅外部方法调用 通过代理进入的邮件被拦截。这意味着 自我调用(实际上是目标对象内的一种方法 目标对象的另一种方法)不会导致实际 运行时的事务,即使被调用的方法标记有 @交易。 此外,代理必须完全初始化才能提供 预期的行为,因此您不应该依赖于此功能 初始化代码(即@PostConstruct)。
UPD
在您的情况下,主要问题是加载了供应商角色的一对多列表。由于没有交易,这是可预见的行为。我希望this topic可以帮助您解决问题,但是无论如何,请问自己-是否真的有必要在@PostCunstruct
中做这样的事情?如果没有,您可以使用projections或jpql constructor来在存储库中实现替代方法,以摆脱连接的实体加载