我想在tomcat容器启动之前通过hibernate会话从tomcat监听器查询数据库 . 这里我得到了org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话错误 . 此外,当尝试使用hibernate会话附加对象时,它会给出错误
我的设置:1 . 有一个tomcat监听器,其中同样实现ServletContextListener 2.通过这个监听器启动spring applicationcontext 3.在spring中配置hibernate和JPA
listener:在这个监听器中,我正在尝试加载我的spring applicationContext并通过hibernate会话调用我的DAO来获取DB数据 . 另外我开始一个线程池来分配任务取决于数据库查询
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
logger.debug("initializing the servletContextListener for AlarmThreadPool...");
try {
String springFileName = sce.getServletContext().getInitParameter("CONFIG_SPRING_FILE");
ApplicationContextContainer.getInstance(springFileName, sce.getServletContext());
IAriCloudDAO ariCloudDAO = (IAriCloudDAO) ApplicationContextContainer.getBean("ariCloudDAO");
logger.debug("got the dao bean...");
if (null != ariCloudDAO) {
System.out.println("got the instace of DAO");
int metricID = 1;
List<CloudAlarmConfig> cloudAlarmConfigs = ariCloudDAO.getAllUsageAlarm(metricID);
logger.info("the DAO entry got as " +cloudAlarmConfigs);
}
ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setNameFormat("alarm-thread-%d")
//.setDaemon(true)
.build();
ScheduledExecutorService exec = Executors.newScheduledThreadPool(2, threadFactory);
servletContext.setAttribute("alarmThreadPool", exec);
}catch (Exception e) {
logger.fatal("ERROR::", e);
}
}
DAO IMPL:
@Override
@Transactional
@SuppressWarnings("unchecked")
public List<CloudAlarmConfig> getAllUsageAlarm(int metricID) {
Session session = mySessionFactory.getCurrentSession();
Query q = session
.createQuery("SELECT e FROM CloudAlarmConfig e WHERE METRIC=:METRIC");
q.setParameter("METRIC", metricID);
logger.debug("query string got as :"+ q.getQueryString());
List<CloudAlarmConfig> cloudAlarmConfigs = q.list();
if (!cloudAlarmConfigs.isEmpty()) {
return cloudAlarmConfigs;
} else {
return new ArrayList<CloudAlarmConfig>();
}
}
JPA实体:
我正在使用LazyInitialization进行实体加入 .
@JsonIgnore
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "USER_ID", referencedColumnName = "ID")
private UserEntity userEntity;
尝试执行DAO调用时获取以下异常 .
org.hibernate.LazyInitializationException:无法在org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)的org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164)初始化代理 - 没有会话.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)位于java.lang.String.valueOf的com.aricent.aricloud.entity.UserEntity _ $$ _ javassist_6.toString(UserEntity _ $$ _ javassist_6.java) (String.java:2902)在java.lang.StringBuilder.append(StringBuilder.java:128)在com.aricent.aricloud.entity.CloudAlarmConfig.toString(CloudAlarmConfig.java:234)在java.lang.String.valueOf( String.java:2902)at java.lang.StringBuilder.append(StringBuilder.java:128)
正如我在几篇文章中所理解的那样,hibernate会话仅针对一个请求生效,然后关闭,实体已从会话中分离出来 . 但是当试图用DAO impl中的下面的代码重新连接它时,它给了我不同的错误
Session session = mySessionFactory.getCurrentSession();
session.update(CloudAlarmConfig.class);
org.hibernate.MappingException:未知实体:在org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1433)在org.hibernate.internal.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:1141)java.lang.Class中在在org.hibernate.event.internal.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:55)在org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:233) DefaultSaveOrUpdateEventListener.java:90)在org.hibernate.internal.SessionImpl.fireUpdate(SessionImpl.java:786)在org.hibernate.internal.SessionImpl.update(SessionImpl.java:778)在org.hibernate.internal.SessionImpl.update (SessionImpl.java:774)at com.aricent.aricloud.dao.AricloudDAOImpl.getAllUsageAlarm(AricloudDAOImpl.java:959)
我怎么能克服这一点 . 请建议 .
1 回答
您正在覆盖
CloudAlarmConfig
类的toString()
方法并尝试访问延迟加载的UserEntity
实例 .所以在你的代码中 -
这使得调用toString方法在内部尝试访问"UserEntity",因此当您尝试访问Hibernate会话之外的实体时,您将获得Lazy异常
org.hibernate.LazyInitializationException: could not initialize proxy - no Session at
.要解决此问题,您必须在会话仍处于打开状态时加载
UserEntity
的实例 .Jens在他的评论中提到了第二个例外,即
org.hibernate.MappingException: Unknown entity: java.lang.Class at
. 代码应该是这样的:这里
cloudAlarmConfig
表示CloudAlarmConfig class
的实例 .Update:
要更新记录,首先应该有一个具有正确id的有效对象 . 所以你可以尝试这样: