当前位置: 首页 > 知识库问答 >
问题:

Hibernate Spring访问WebSphere数据源

时旭东
2023-03-14

我正在从事一个门户项目,在那里我被迫使用WebSpherePortal、SpringPortlet MVC和Hibernate。我在配置Spring和Hibernate方面没有太多经验,因此非常感谢您提供的各种帮助
我在WebSphere 7.0.0.25(安装了Portal 6.1)上创建了一个JDBC数据源,JNDI名称为JDBC/eshop。然后我指定JAAS身份验证别名,并将其设置为容器管理的身份验证别名。测试连接尝试成功,所以我想数据源的配置是合适的。我的下一步是在网上做参考资料。xml:

<resource-ref>    
    <description>DB Connection</description>    
    <res-ref-name>eshop</res-ref-name>   
    <res-type>javax.sql.DataSource</res-type>    
    <res-auth>Container</res-auth>   
</resource-ref>

为了将res ref name绑定到ibm web bnd中的实际JNDI名称,我添加了以下行:

<resource-ref name="eshop" binding-name="java:comp/env/jdbc/eshop" />

现在我的Hibernate实体:

@Entity
@Table(name = "HIBERNATE_TEST", schema = "SCHEME_NAME")
public class HibernateTest implements java.io.Serializable {

private short id;
private String text;

public HibernateTest() {
}

public HibernateTest(String text) {
    this.text = text;
}


@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "ID")
public short getId() {
    return this.id;
}

public void setId(short id) {
    this.id = id;
}

@Column(name = "TEXT", nullable = false, length = 10)
public String getText() {
    return this.text;
}

public void setText(String text) {
    this.text = text;
}

HibernateTestDAO:

@Repository("hibernateTestDAO")
@Transactional
public class HibernateTestDAO  implements GenericDAO<HibernateTest> {
@Autowired
private SessionFactory sessionFactory;

private Session sess;

public HibernateTestDAO ()  {

}

public SessionFactory getSessionFactory() {
    return sessionFactory;
}

public void setSessionFactory(SessionFactory sf) {
    sessionFactory = sf;
}

public boolean add(HibernateTest item) {
    boolean isAdded = false;
    try {
        sess = sessionFactory.getCurrentSession();
        sess.persist(item);
        isAdded =  true;
    } catch (Exception e) {
        e.printStackTrace();
    } 
    return isAdded;
}

public boolean edit(HibernateTest item) {
    boolean isEdited = false;
    try {
        sess = sessionFactory.getCurrentSession();
        item = (HibernateTest)sess.merge(item);
        sess.update(item);
        isEdited =  true;
    } catch (Exception e) {
        e.printStackTrace();
    } 
    return isEdited;
}

public boolean delete(HibernateTest item) {
    boolean isDeleted = false;
    try {
        sess = sessionFactory.getCurrentSession();
        item = (HibernateTest)sess.merge(item);
        sess.delete(item);
        isDeleted =  true;
    } catch (Exception e) {
        e.printStackTrace();
    } 
    return isDeleted;
}

@SuppressWarnings("unchecked")
@Override
@Transactional(readOnly = true)
public List<HibernateTest> getAll() {
    List<HibernateTest> l = new ArrayList<HibernateTest>(0);
    try {
        sess = sessionFactory.getCurrentSession();
        Query q = sess.createQuery("FROM HibernateTest");
        l = (List<HibernateTest>) q.list();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return l;
}

@Override
@Transactional(readOnly = true)
public HibernateTest getByID(long id) {
    try {
        sess = sessionFactory.getCurrentSession();
        return (HibernateTest)sess.get(HibernateTest.class, new Short((short)id));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
}

如您所见,我不想使用程序管理的事务。我了解到,Spring有WebSphereUowTransactionManager类来管理WebSphere数据源的事务。我已经尝试了这个配置(应用ontext.xml):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd    
    http://www.springframework.org/schema/jee
    http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <context:annotation-config /> 
    <context:component-scan base-package="test.dao,test.entities,test.portlet.controller" />

        <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/eshop"/>
    <property name="lookupOnStartup" value="false"/>
    <property name="cache" value="true" />
    <property name="proxyInterface"  value="javax.sql.DataSource" />
    </bean>

    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory"     class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="annotatedClasses">
        <list>
            <value>test.entities.HibernateTest</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
          <prop key="hibernate.dialect">org.hibernate.dialect.DB2Dialect</prop>
          <prop key="hibernate.show_sql">true</prop>
          <!--           IBM WAS SPECIFIC             -->          
          <prop key="hibernate.connection.datasource">jdbc/eshop</prop>
          <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</prop>
          <prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</prop>
          <prop key="hibernate.transaction.jta.platform">org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform</prop> 
          <!--           /END IBM WAS SPECIFIC        -->
        </props>
    </property>
    </bean>

    <bean id="transactionManager"
    class="org.springframework.transaction.jta.WebSphereUowTransactionManager">
        <property name="userTransactionName" value="java:comp/UserTransaction" />
    </bean>  

    <bean id="hibernateTestDAO" class="test.dao.HibernateTestDAO" /> 

    </beans> 

,但它会导致这个例外链:

错误500:org。springframework。豆。工厂BeanCreationException:创建名为“transactionManager”的bean时出错,该bean在ServletContext资源[/WEB-INF/applicationContext.xml]中定义:调用init方法失败;嵌套的异常是org。springframework。交易TransactionSystemException:JTA UserTransaction在JNDI位置[java:comp/UserTransaction]不可用;嵌套的异常是org。springframework。jndi。TypeMismatchNamingException:JNDI位置[java:comp/UserTransaction]上可用的[class com.ibm.ws.tx.jta.UserTransactionImpl]类型的对象不能分配给[javax.transaction.UserTransaction]

我知道这种情况下的典型解决方案是删除jta。jar来自类路径,但我在类路径中没有这个jar!我只是不明白IBM如何使用特定于供应商的库来创建UserTransaction类,但我应该让它工作起来,所以我需要您的帮助来配置我的应用程序。

我还想补充一点,我围绕这个问题工作了大约3天,尝试了不同的配置,但遗憾的是没有成功。所以我决定使用这个源代码中的一个工作(正如作者所说)配置作为起点,在这里提出这个问题。我已经没有办法解决这个问题了,所以我需要帮助。

使现代化

我可以用Hibernate对当前事务的抱怨来解决这个问题:没有

public class TestDIController extends AbstractController implements ApplicationContextAware{

private ApplicationContext appCtx;

@Override
public ModelAndView handleRenderRequest(RenderRequest request,
        RenderResponse response) throws Exception {
    appCtx = getApplicationContext();
    System.out.println(UserTransaction.class.getClassLoader());
    @SuppressWarnings("rawtypes")
    GenericDAO cd = (GenericDAO)appCtx.getBean("hibernateTestDAO");
    ModelAndView m = new ModelAndView("test").addObject("list", cd.getAll());
    return m;
}
}

当ModelAndView实例试图向自身添加新对象时,HibernateTestDAO的代码行l=(列表

组织。冬眠例外SQLGrammarException:无法打开连接

...一些堆栈痕迹...

原因:java。sql。SQLException:[jcc][t4][10205][11234][3.58.81]不支持空用户ID。ERRORCODE=-4461,SQLSTATE=42815DSRA0010E:SQL State=42815,错误代码=-4

这个错误令人困惑,因为我已经指定了容器管理的身份验证别名,请参见下图


共有1个答案

井旺
2023-03-14

com.ibm.ws.tx.jta.UserTransactionImpl实现javax.transaction.UserTransaction。你的代码很好。最有可能的是,您正在使用父最后一个ClassLoader策略,并且在应用程序中的一个jars中有javax.transaction.UserTransaction

试着摆脱javax。交易用户事务来自应用程序

 类似资料:
  • 考虑以下队列防御: 设置AUTHREC OBJTYPE(QMGR)组('mq-user')AUTHADD(INQ,DSP,CONNECT) MCAUSER在DEFINE CHANNEL和setchlauth中的含义是什么? tcs-mq-user应该属于mq-user组吗? 这是否意味着只有tcs-mq-user在绑定模式下可以访问队列管理器?现在,如果我想在绑定模式下为另一个用户提供访问权限,我

  • 问题内容: 如果通过网络服务获得以下数据: 我如何访问第二个col1? 如下: 给我: 问题答案: 它是一个包含2个元素的数组,其中包含和,所以类似: (是第一个元素,然后选择“ col1”)

  • ActiveX Data Objects (ADO) 是一项容易使用并且可扩展的将数据库访问添加到 Web 页的技术。可以使用 ADO 去编写紧凑简明的脚本以便连接到 Open Database Connectivity (ODBC) 兼容的数据库和 OLE DB 兼容的数据源。如果您是一个对数据库连接有一定了解的脚本编写人员,那么您将发现 ADO 命令语句并不复杂而且容易掌握。同样地,如果您是一

  • 参考文档的这一部分是关于数据访问和数据访问层与业务/service层之间的交互。 详细介绍了Spring对事务管理的全方位支持,然后深入讲述了更种数据访问框架以及它们与Spring Framework的集成。

  • 对许多Web应用程序而言,数据库都是其核心所在。数据库几乎可以用来存储你想查询和修改的任何信息,比如用户信息、产品目录或者新闻列表等。 Go没有内置的驱动支持任何的数据库,但是Go定义了database/sql接口,用户可以基于驱动接口开发相应数据库的驱动,5.1小节里面介绍Go设计的一些驱动,介绍Go是如何设计数据库驱动接口的。5.2至5.4小节介绍目前使用的比较多的一些关系型数据驱动以及如何使

  • 程序运行的时候,数据都是在内存中的。当程序终止的时候,通常都需要将数据保存到磁盘上,无论是保存到本地磁盘,还是通过网络保存到服务器上,最终都会将数据写入磁盘文件。 而如何定义数据的存储格式就是一个大问题。如果我们自己来定义存储格式,比如保存一个班级所有学生的成绩单: 名字 成绩 Michael 99 Bob 85 Bart 59 Lisa 87 你可以用一个文本文件保存,一行保存一个学生,用,隔开