Весенний ботинок. Нет прокси при попытке распечатать несохраненный объект - PullRequest
1 голос
/ 16 апреля 2019

Исходя из обычного проекта 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)

1 Ответ

1 голос
/ 16 апреля 2019

Вы прокомментировали, что в вашей Job сущности есть @XToMany отношения.Поскольку все-ко-многим равны Lazy, это приводит к LazyInitializationException.Эти поля не могут быть созданы в транзакции, так как они были переданы методу, помеченному @Transactional (он был инициализирован вне области транзакции).В качестве обходного пути вам придется перейти configDao.findAll().get(0) к транзакционному методу:

@Service
public class TestService {

   @Autowired
   private ConfigDao configDao;

   private static final Logger logger = LoggerFactory.getLogger("test");

   @Transactional
   public void addJob() {
      Job job = configDao.findAll().get(0);
      logger.info("Adding job {}", job);
   }
   ...
}

@Service
public class Tests {
   @Autowired
   private TestService service;

   @EventListener(ApplicationReadyEvent.class)
   public void testJobAdd() {
      Job job = new Job();
      job.setConfig();
      service.addJob(job);
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...