0

トランザクション マネージャー Bean を作成しようとすると、Spring からエラーが発生します。以下に私のJavaクラスと構成ファイルを投稿しています。

foo.bar/HelloApp.java :

package foo.bar;

import com.mkyong.stock.bo.StockBo;
import com.mkyong.stock.model.StockEntity;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

        StockBo stockBo = (StockBo)context.getBean("stockBo");

        //insert
        StockEntity stock = new StockEntity();
        stock.setStockCode("7668");
        stock.setStockName("HAIO");
        stockBo.save(stock);

        //select
        StockEntity stock2 = stockBo.findByStockCode("7668");
        System.out.println(stock2);

        //update
        //stock2.setStockName("HAIO-1");
        //stockBo.update(stock2);

        //delete
        //stockBo.delete(stock2);

        System.out.println("Done");
    }
}

com.mkyong.stock.bo/StockBoImpl.java :

package com.mkyong.stock.bo;

import com.mkyong.stock.dao.StockDao;
import com.mkyong.stock.model.StockEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service("stockBo")
@Transactional(propagation = Propagation.SUPPORTS)
public class StockBoImpl implements StockBo{

    @Autowired
    StockDao stockDao;

    public void setStockDao(StockDao stockDao)
    {
        this.stockDao = stockDao;
    }

    @Override
    public void save(StockEntity stock) {
        stockDao.save(stock);
    }

    @Override
    public void update(StockEntity stock) {
        stockDao.save(stock);
    }

    @Override
    public void delete(StockEntity stock) {
        stockDao.delete(stock);
    }

    @Override
    public StockEntity findByStockCode(String stockCode) {
        return stockDao.findByStockCode(stockCode);
    }
}

com.mkyong.stock.dao/StockDaoImpl.java :

package com.mkyong.stock.dao;

import com.mkyong.stock.model.StockEntity;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;


@Repository("stockDao")
public class StockDaoImpl implements StockDao{

    private SessionFactory sessionFactory;

    @Autowired
    public StockDaoImpl(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

    private Session currentSession()
    {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public void save(StockEntity stock) {
        currentSession().save(stock);
    }

    @Override
    public void update(StockEntity stock) {
        currentSession().update(stock);
    }

    @Override
    public void delete(StockEntity stock) {
        currentSession().delete(stock);
    }

    @Override
    public StockEntity findByStockCode(String stockCode) {
        return (StockEntity)currentSession().get(StockEntity.class, stockCode);
    }
}

com.mkyong.stock.model/StockEntity.java :

package com.mkyong.stock.model;

import javax.persistence.*;

import java.io.Serializable;

import static javax.persistence.GenerationType.IDENTITY;


@javax.persistence.Table(name = "stock", schema = "", catalog = "mkyong",
        uniqueConstraints = {
                @UniqueConstraint(columnNames = "STOCK_NAME"),
                @UniqueConstraint(columnNames = "STOCK_CODE")
        }
)
@Entity
public class StockEntity implements Serializable{
    private int stockId;
    private String stockCode;
    private String stockName;

    //---constructors
    public StockEntity() {
    }

    public StockEntity(String stockCode, String stockName) {
        this.stockCode = stockCode;
        this.stockName = stockName;
    }

    //---getters and setters
    @javax.persistence.Column(name = "STOCK_ID", unique = true, nullable = false, insertable = true, updatable = true, length = 10, precision = 0)
    @Id
    @GeneratedValue(strategy = IDENTITY)
    public int getStockId() {
        return stockId;
    }

    public void setStockId(int stockId) {
        this.stockId = stockId;
    }



    @javax.persistence.Column(name = "STOCK_CODE", unique = true, nullable = false, insertable = true, updatable = true, length = 10, precision = 0)
    @Basic
    public String getStockCode() {
        return stockCode;
    }

    public void setStockCode(String stockCode) {
        this.stockCode = stockCode;
    }



    @javax.persistence.Column(name = "STOCK_NAME", unique = true, nullable = false, insertable = true, updatable = true, length = 20, precision = 0)
    @Basic
    public String getStockName() {
        return stockName;
    }

    public void setStockName(String stockName) {
        this.stockName = stockName;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        StockEntity that = (StockEntity) o;

        if (stockId != that.stockId) return false;
        if (stockCode != null ? !stockCode.equals(that.stockCode) : that.stockCode != null) return false;
        if (stockName != null ? !stockName.equals(that.stockName) : that.stockName != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = stockId;
        result = 31 * result + (stockCode != null ? stockCode.hashCode() : 0);
        result = 31 * result + (stockName != null ? stockName.hashCode() : 0);
        return result;
    }

    @Override
    public String toString()
    {
        return "Stock [stockCode=" + stockCode + ", stockId=" + stockId + ", stockName=" + stockName + "]";
    }
}

resources/hibernate.cfg.xml :

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.url">jdbc:mysql://localhost:3306/mkyong</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.username">root</property>
        <property name="connection.password">mypassword</property>

        <property name="hibernate.current_session_context_class">thread</property>

        <!-- DB schema will be updated if needed -->
        <property name="hbm2ddl.auto">create</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <mapping class="com.mkyong.stock.model.StockEntity"/>
        <mapping resource="mapping.xml"/>
    </session-factory>
</hibernate-configuration>

リソース/spring-config.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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="configLocation" value="hibernate.cfg.xml"/>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <context:annotation-config />
    <context:component-scan base-package="foo.bar, com.mkyong.stock"/>

    <tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

そして、ここに私が得るエラースタックトレースがあります:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [spring-config.xml]: Invocation of init method failed; nested exception is org.hibernate.service.UnknownUnwrapTypeException: Cannot unwrap to requested type [javax.sql.DataSource]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1486)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at foo.bar.HelloApp.main(HelloApp.java:10)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.hibernate.service.UnknownUnwrapTypeException: Cannot unwrap to requested type [javax.sql.DataSource]
    at org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl.unwrap(DriverManagerConnectionProviderImpl.java:85)
    at org.springframework.orm.hibernate4.SessionFactoryUtils.getDataSource(SessionFactoryUtils.java:91)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.afterPropertiesSet(HibernateTransactionManager.java:252)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1545)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1483)
    ... 17 more
4

1 に答える 1

2

一目で際立っているのは、設定したプロパティです。私が知っていることから、Hibernate は、休止状態のプロパティで指定した接続プロパティを見つけることを期待しています。( http://docs.huihoo.com/hibernate/hibernate-reference-2.1.7/session-configuration.htmlから以下を参照)

 Hibernate will obtain (and pool) connections using java.sql.DriverManager if you set the following properties:

Table 3.1. Hibernate JDBC Properties
Property name   Purpose
hibernate.connection.driver_class   jdbc driver class
hibernate.connection.url    jdbc URL
hibernate.connection.username   database user
hibernate.connection.password   database user password
hibernate.connection.pool_size  maximum number of pooled connections

あなたの場合、これは以下を置き換えることを意味します:

        <property name="connection.url">jdbc:mysql://localhost:3306/mkyong</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.username">root</property>
        <property name="connection.password">mypassword</property>

あり(これはmykongで表示される方法です):

        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mkyong</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">mypassword</property>

別の可能な方法は、JDBC DataSource を指定して、SessionFactory に注入することです。たとえば、次のようになります。

 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
        <property name="url" value="jdbc:sqlserver://<Host>:<Port>;databaseName=<DBName>;" />
        <property name="username" value=<username> />
        <property name="password" value=<password> />
   </bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
......
于 2013-04-29T06:42:25.253 に答える