用于在多个类中使用sessionFactory的bean

时间:2013-11-21 19:11:10

标签: java spring hibernate spring-mvc

我正在做this tutorial,但我不得不在其他小调整中升级到Hibernate 4。因此,我不得不在第二个类文件中使用sessionFactory,而不是仅仅在本教程中使用的单个类文件中使用它。 sessionFactory的使用导致以下错误:

SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException:  
Error creating bean with name 'documentController':  
Injection of autowired dependencies failed;  
nested exception is org.springframework.beans.factory.BeanCreationException:  
Could not autowire field:  
private net.viralpatel.docmanager.dao.DocumentDAO net.viralpatel.docmanager.controller.DocumentController.documentDao;  
nested exception is org.springframework.beans.factory.BeanCreationException:  
Error creating bean with name 'documentDAO':  
Injection of autowired dependencies failed;  
nested exception is org.springframework.beans.factory.BeanCreationException:  
Could not autowire field: private org.hibernate.SessionFactory net.viralpatel.docmanager.dao.DocumentDAO.sessionFactory;  
nested exception is java.lang.NoClassDefFoundError:  
Lorg/hibernate/cache/CacheProvider;  

如何更改代码以解决此问题?我将附上bean,以及现在调用sessionFactory的两个类文件。

这是spring-servlet.xml中的bean定义:

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation">
        <value>classpath:hibernate.cfg.xml</value>
    </property>
    <property name="configurationClass">
        <value>org.hibernate.cfg.AnnotationConfiguration</value>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${jdbc.dialect}</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.connection.SetBigStringTryClob">true</prop>
            <prop key="hibernate.jdbc.batch_size">0</prop>
        </props>
    </property>
</bean>  

这是DocumentDAO类,它使用sessionFactory:

@Repository
public class DocumentDAO {

    @Autowired
    private SessionFactory sessionFactory;

    @Transactional
    public void save(Document document) {
        Session session = sessionFactory.getCurrentSession();
        session.save(document);
    }

    @Transactional
    public List<Document> list() {
        Session session = sessionFactory.getCurrentSession();
        List<Document> documents = null;
        try {documents = (List<Document>)session.createQuery("from Document").list();} 
        catch (HibernateException e) {e.printStackTrace();}
        return documents;
    }

    @Transactional
    public Document get(Integer id) {
        Session session = sessionFactory.getCurrentSession();
        return (Document)session.get(Document.class, id);
    }

    @Transactional
    public void remove(Integer id) {
        Session session = sessionFactory.getCurrentSession();
        Document document = (Document)session.get(Document.class, id);
        session.delete(document);
    }
}

这是DocumentController的代码,我必须将sessionFactory作为升级到Hibernate 4的一部分添加到其中:

@Controller
public class DocumentController {
    @Autowired
    private DocumentDAO documentDao;
    @Autowired
    SessionFactory sessionFactory;

    @RequestMapping("/index")
    public String index(Map<String, Object> map) {
        try {
            map.put("document", new Document());
            map.put("documentList", documentDao.list());
        }catch(Exception e) {e.printStackTrace();}
        return "documents";
    }

    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public String save(@ModelAttribute("document") Document document, @RequestParam("file") MultipartFile file) {
        System.out.println("Name:" + document.getName());
        System.out.println("Desc:" + document.getDescription());
        System.out.println("File:" + file.getName());
        System.out.println("ContentType:" + file.getContentType());

        try {
            Blob blob = Hibernate.getLobCreator(sessionFactory.getCurrentSession()).createBlob(file.getInputStream(), file.getSize());
            document.setFileName(file.getOriginalFilename());
            document.setContent(blob);
            document.setContentType(file.getContentType());
        } catch (IOException e) {e.printStackTrace();}
        try {documentDao.save(document);} 
        catch(Exception e) {e.printStackTrace();}
        return "redirect:/index.html";
    }

    @RequestMapping("/download/{documentId}")
    public String download(@PathVariable("documentId") Integer documentId, HttpServletResponse response) {
        Document doc = documentDao.get(documentId);
        try {
            response.setHeader("Content-Disposition", "inline;filename=\"" +doc.getFileName()+ "\"");
            OutputStream out = response.getOutputStream();
            response.setContentType(doc.getContentType());
            IOUtils.copy(doc.getContent().getBinaryStream(), out);
            out.flush();
            out.close();
        } 
        catch (IOException e) {e.printStackTrace();} 
        catch (SQLException e) {e.printStackTrace();}
        return null;
    }

    @RequestMapping("/remove/{documentId}")
    public String remove(@PathVariable("documentId") Integer documentId) {
        documentDao.remove(documentId);
        return "redirect:/index.html";
    }
}

EDIT /解答:

要解决此问题,我需要进行以下更改:

Change Hibernate3 to Hibernate4 in the sessionFactory AND transactionManager beans  
Remove the configLocation and configurationClass properties from sessionFactory bean  
Add packagestoscan property to sessionFactory bean  
Add a list of values within the annotatedclasses property of the sessionFactory bean
Keep other things the same  

1 个答案:

答案 0 :(得分:1)

引用另一个答案:

  

将您的AnnotationSessionFactoryBean更改为org.springframework.orm.hibernate4.LocalSessionFactoryBean(Hibernate 4),您将会很高兴。 AnnotationSessionFactoryBean已替换为LocalSessionFactoryBean,因为它现在进行类路径扫描。

Original answer

类似的东西:

    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource"></property>
        <property name="annotatedClasses">
            <list>
                <value>com...</value>
                all the annotated classes come here
            </list>
        </property>
        <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${jdbc.dialect}</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.connection.SetBigStringTryClob">true</prop>
            <prop key="hibernate.jdbc.batch_size">0</prop>
        </props>
        </property>
    </bean>