Исходя из обычного проекта Spring Boot, у меня есть сущность:
@Entity
public class Job {
@Id
@GeneratedValue
private long id;
@ManyToOne(fetch = EAGER)
@JoinColumn
private Config config;
...
}
toString () обычно формируется Eclipse для регулярной печати полей.
Когда я пытаюсь сделать базовую симуляцию рабочего процесса и выполняю:
@Service
public class TestService {
private static final Logger logger = LoggerFactory.getLogger("test");
@Transactional
public void addJob(Job job) {
logger.info("Adding job {}", job);
}
...
}
@Service
public class Tests {
@Autowired
private TestService service;
@Autowired
private ConfigDao configDao;
@EventListener(ApplicationReadyEvent.class)
public void testJobAdd() {
Job job = new Job();
job.setConfig(configDao.findAll().get(0));
service.addJob(job);
}
}
И это дает исключение "Нет сеанса" для элементов @ManyToOne объекта Job.
Я понимаю, что это далеко от обычного способа добиться цели, но все же я удивляюсь, почему происходит это исключение. «Config» доставляется при создании pojo, поэтому никакой «выборки» не должно быть.
Я могу сначала сохранить объект, а затем вернуть полностью кэшированную сущность, что сработает, но я хочу записать детали Job до того, как объект достигнет JPA.
Stack:
019-04-16 15:07:52 ERROR [localhost-startStop-1] SpringApplication.reportFailure: Application run failed
org.hibernate.LazyInitializationException: could not initialize proxy [org.applebase.AutomationAgent.entity.sessionConfig.SessionConfig#1403] - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:169)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:309)
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:45)
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95)
at org.applebase.AutomationAgent.entity.sessionConfig.SessionConfig$HibernateProxy$GOSm9GNJ.getName(Unknown Source)
at org.applebase.AutomationAgent.service.impl.JobServiceImpl.save(JobServiceImpl.java:28)
at org.applebase.AutomationAgent.service.impl.JobServiceImpl$$FastClassBySpringCGLIB$$13b2fdc0.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at org.applebase.AutomationAgent.service.impl.JobServiceImpl$$EnhancerBySpringCGLIB$$ae28e0fc.save(<generated>)
at org.applebase.AutomationAgent.service.impl.SomeTestService.formingAJob(SomeTestService.java:58)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:261)
at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:179)
at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:142)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:402)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:359)
at org.springframework.boot.context.event.EventPublishingRunListener.running(EventPublishingRunListener.java:105)
at org.springframework.boot.SpringApplicationRunListeners.running(SpringApplicationRunListeners.java:78)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:332)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:157)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:137)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:91)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:171)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5245)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1420)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1410)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.base/java.lang.Thread.run(Thread.java:844)