我正在做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";
}
}
要解决此问题,我需要进行以下更改:
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
答案 0 :(得分:1)
引用另一个答案:
将您的AnnotationSessionFactoryBean更改为org.springframework.orm.hibernate4.LocalSessionFactoryBean(Hibernate 4),您将会很高兴。 AnnotationSessionFactoryBean已替换为LocalSessionFactoryBean,因为它现在进行类路径扫描。
类似的东西:
<!-- 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>