精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-06-05
ahuaxuan 写道 原来你是在liferay里啊,但是我有一点不明白,你是如何做到把HibernateConfiguration的实例赋给SessionFactoryImplementor 的引用的呢,这两个类型完全不一样啊,而且hibenate包中的ssionFactoryImplementor类根本没有getCurrentSession()方法,于是我就迷惑了,难道这是liferay对hibernate的封装
请看 liferay中操作数据库的 HibernateUtil.java 这个类,类里面注射了SessionFactoryImplementor, 而不是 SessionFactory 这个类: public class HibernateUtil { public static final String SPRING_HIBERNATE_DATA_SOURCE = PropsUtil.get(PropsUtil.SPRING_HIBERNATE_DATA_SOURCE); public static final String SPRING_HIBERNATE_SESSION_FACTORY = PropsUtil.get(PropsUtil.SPRING_HIBERNATE_SESSION_FACTORY); public static final String COUNT_COLUMN_NAME = "COUNT_VALUE"; public static Connection getConnection() throws SQLException { return getDataSource().getConnection(); } public static DataSource getDataSource() { if (_dataSource == null) { _dataSource = (DataSource)BeanLocatorUtil.locate( SPRING_HIBERNATE_DATA_SOURCE); } return _dataSource; } public static SessionFactoryImplementor getSessionFactory() { return getSessionFactory(SPRING_HIBERNATE_SESSION_FACTORY); } public static SessionFactoryImplementor getSessionFactory( String sessionFactoryName) { if (sessionFactoryName.equals(SPRING_HIBERNATE_SESSION_FACTORY)) { if (_sessionFactory == null) { LocalSessionFactoryBean lsfb = (LocalSessionFactoryBean)BeanLocatorUtil.locate( sessionFactoryName); _sessionFactory = (SessionFactoryImplementor)lsfb.getObject(); } return _sessionFactory; } else { SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor)_sessionFactories.get( sessionFactoryName); if (sessionFactory == null) { LocalSessionFactoryBean lsfb = (LocalSessionFactoryBean)BeanLocatorUtil.locate( sessionFactoryName); sessionFactory = (SessionFactoryImplementor)lsfb.getObject(); _sessionFactories.put(sessionFactoryName, sessionFactory); } return sessionFactory; } } public static Dialect getDialect() { return getDialect(SPRING_HIBERNATE_SESSION_FACTORY); } public static Dialect getDialect(String sessionFactoryName) { return getSessionFactory(sessionFactoryName).getDialect(); } public static void closeSession(Session session) { try { if (session != null) { // Let Spring manage sessions //session.close(); } } catch (HibernateException he) { _log.error(he.getMessage()); } } public static Session openSession() throws HibernateException { return openSession(SPRING_HIBERNATE_SESSION_FACTORY); } public static Session openSession(String sessionFactoryName) throws HibernateException { SessionFactoryImplementor sessionFactory = getSessionFactory(sessionFactoryName); return openSession(sessionFactory); } public static Session openSession(SessionFactory sessionFactory) throws HibernateException { // Let Spring manage sessions return sessionFactory.getCurrentSession(); } public static String getCountColumnName() { return COUNT_COLUMN_NAME; } private static Log _log = LogFactory.getLog(HibernateUtil.class); private static DataSource _dataSource; private static SessionFactoryImplementor _sessionFactory; private static Map _sessionFactories = CollectionFactory.getHashMap(); } liferay完全用 这个 HibernateUtil类操作的数据库.奥妙也全都在这里类里面.不明白 liferay为什么注入的是SessionFactoryImplementor? 但是所有他都是这样操作的数据库,得到的session,尔我只要使用就报刚才的错误,好像被他完全隔绝在在外边? 无论如何也不能在 liferay中使用 声明的事务创建session? 你看这个类 hibernateUtil有什么特别的地方么? |
|
返回顶楼 | |
发表时间:2007-06-05
你仔细看一下LocaleSessionFactoryBean第1064行,SessionFactoryUtils.doGetSession((SessionFactory) proxy, false),就是这个false,导致在SessionFactoryUtil的第363行抛出了异常,异常得信息就是这个“throw new IllegalStateException("No Hibernate Session bound to thread, " +
"and configuration does not allow creation of non-transactional one here");” 由此可以看出,这个应该还是配置得问题,导致事务没有正确的起作用 |
|
返回顶楼 | |
发表时间:2007-06-05
ahuaxuan 写道 你仔细看一下LocaleSessionFactoryBean第1064行,SessionFactoryUtils.doGetSession((SessionFactory) proxy, false),就是这个false,导致在SessionFactoryUtil的第363行抛出了异常,异常得信息就是这个“throw new IllegalStateException("No Hibernate Session bound to thread, " +
"and configuration does not allow creation of non-transactional one here");” 由此可以看出,这个应该还是配置得问题,导致事务没有正确的起作用 你好,我最开始的发表中说道: 引用 很明显是因为那个 allowCreate的问题,当没有事务启动的时候,getCurrentSession是无法创建Session的! 说明配置事务没有成功!但是我的配置已经和例子一摸一样了啊~
应该是配置的问题,关键是: 哪里配置错了呢,我的配置已经和例子一摸一样了啊? 不知道你注意过 liferay的spring配置没有,非常诡异,他居然把 transaction的拦截器注入到其他类中使用,没见过有这样用: <bean id="com.liferay.portal.service.AccountLocalService.professional" class="com.liferay.portal.service.impl.AccountLocalServiceImpl" lazy-init="true" /> <bean id="com.liferay.portal.service.AccountLocalService.transaction" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" lazy-init="true"> <property name="transactionManager"> <ref bean="liferayTransactionManager" /> </property> <property name="target"> <ref bean="com.liferay.portal.service.AccountLocalService.professional" /> </property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> <bean id="com.liferay.portal.service.AccountLocalServiceFactory" class="com.liferay.portal.service.AccountLocalServiceFactory" lazy-init="true"> <property name="service"> <ref bean="com.liferay.portal.service.AccountLocalService.transaction" /> </property> </bean> 居然把这个"com.liferay.portal.service.AccountLocalService.transaction" 拦截事务管理器注入到了另一个bean中,不知道是何用意? 难道不按照他这个奇怪的做法就行不通? 但是我还是想知道到底是因为什么? 是不是用了 spring什么高级的特性? |
|
返回顶楼 | |
发表时间:2007-06-05
它这里的“com.liferay.portal.service.AccountLocalService.transaction”这个bean是由org.springframework.transaction.interceptor.TransactionProxyFactoryBean生成的一个代理对象,这个bean实质上是一个com.liferay.portal.service.impl.AccountLocalServiceImpl,只不过外面加了一个spring的事务代理,使得“com.liferay.portal.service.AccountLocalService.professional”这个bean的方法可以进行spring的事务管理,要由spring进行事务管理都要是要生成代理的。
|
|
返回顶楼 | |
发表时间:2007-06-06
lujh99 写道 它这里的“com.liferay.portal.service.AccountLocalService.transaction”这个bean是由org.springframework.transaction.interceptor.TransactionProxyFactoryBean生成的一个代理对象,这个bean实质上是一个com.liferay.portal.service.impl.AccountLocalServiceImpl,只不过外面加了一个spring的事务代理,使得“com.liferay.portal.service.AccountLocalService.professional”这个bean的方法可以进行spring的事务管理,要由spring进行事务管理都要是要生成代理的。
我在 com.liferay.portal.service.AccountLocalServiceFactory 这个类中应该怎样得到这个service呢? 这样注入后, getService返回什么呢? 如果我返回com.liferay.portal.service.AccountLocalService.professional,会报错说类型不一致,应该返回代理 XXXProxy,而不是com.liferay.portal.service.AccountLocalService.professional? |
|
返回顶楼 | |
发表时间:2007-06-06
我记得org.springframework.transaction.interceptor.TransactionProxyFactoryBean中有个属性,名字忘记了,意思是代理目标类,要设为true的,否则生成的代理对象不会instanceof目标类的。
|
|
返回顶楼 | |
发表时间:2007-06-06
之前没有搞过liferay,所以看到奇怪的配置时使我想到其他地方,于是昨天我把hibernate中sessionfactory相关的代码,spring中事务相关的代码又看了一下,也搞明白了很多东西,觉得配置上好像确实没有什么问题(我是指此类配置如果用在一般的spring+hibernate中是没问题的)
于是我有一个疑问,你在测试那个testquery方法的时候是写在什么地方的,你不会在testutil里调用这个testquery方法的吧 lyo 写道 lujh99 写道 它这里的“com.liferay.portal.service.AccountLocalService.transaction”这个bean是由org.springframework.transaction.interceptor.TransactionProxyFactoryBean生成的一个代理对象,这个bean实质上是一个com.liferay.portal.service.impl.AccountLocalServiceImpl,只不过外面加了一个spring的事务代理,使得“com.liferay.portal.service.AccountLocalService.professional”这个bean的方法可以进行spring的事务管理,要由spring进行事务管理都要是要生成代理的。
我在 com.liferay.portal.service.AccountLocalServiceFactory 这个类中应该怎样得到这个service呢? 这样注入后, getService返回什么呢? 如果我返回com.liferay.portal.service.AccountLocalService.professional,会报错说类型不一致,应该返回代理 XXXProxy,而不是com.liferay.portal.service.AccountLocalService.professional? 在代理的时候可以设置接口,这样注入的时候,用接口注入就不会有这种问题了 ps:楼上凌晨3点还在网上啊 |
|
返回顶楼 | |
发表时间:2007-06-06
我的 TestUtil类:
public class TestUtil { private static SessionFactoryImplementor sessionFactory; public SessionFactoryImplementor getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactoryImplementor factory) { sessionFactory = factory; } public List testquery(){ List list=new ArrayList(); Session hsession=this.getSessionFactory().getCurrentSession(); list=hsession.createQuery("from UserImpl as u").list(); hsession.close(); return list; } } 我在jsp中的测试代码: org.springframework.context.ApplicationContext ctx = new org.springframework.context.support.ClassPathXmlApplicationContext(new String []{"META-INF/ext-spring-professional.xml","classpath*:META-INF/portal-spring-professional.xml","classpath*:META-INF/counter-spring-professional.xml"}); Object objBean=ctx.getBean("com.liferay.portlet.lyo.service.persistence.TestUtil"); out.println("get bean: "+objBean); com.liferay.portlet.lyo.service.persistence.TestUtil th=(com.liferay.portlet.lyo.service.persistence.TestUtil)objBean; java.util.List list=th.testquery(); 其中加载了我得 ext-spring-professional.xml和 liferay系统的那些xml,包括他创建数据源的xml.写的应该没问题吧? 最近有点失眠,我电脑也总忘关,有时候起来就看看论坛,呵呵~ |
|
返回顶楼 | |
发表时间:2007-06-06
改成Object objBean=ctx.getBean("myProductService");呢?
|
|
返回顶楼 | |
发表时间:2007-06-06
引用 Object objBean=ctx.getBean("com.liferay.portlet.lyo.service.persistence.TestUtil");
你取了一个没有被事务代理过的对象的引用,所以不能正常启动事务,确实应该取myProductService,也就是说应该取代理才对。 |
|
返回顶楼 | |