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

使用Spring3对Hibernate4XML进行最小配置,用于基于注释的事务管理和对象映射?

曾英睿
2023-03-14

假设我已经有了一个工作的Spring项目,那么在Hibernate4中添加Spring3XML配置所需的最小配置量是多少?我希望使用基于注释的事务管理,并使用注释映射对象。

注:这是一个自我回答问题

共有1个答案

步联
2023-03-14

我发现将Hibernate与Spring的XML配置一起使用相当直观,但是如果您以前从未将其添加到项目中,那么正确工作可能会很痛苦。使用Spring的XML配置是我首选的Hibernate 4选项。

所以你已经建立了一个Spring项目,一切都正常了。现在要添加Hibernate。

我总是喜欢在WEB-INF目录中的一个名为database-servlet.xml的单独的XML文件中配置Hibernate,但是名称并不重要,只要它在类路径上。

我的新数据库servlet。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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

</beans>

您会注意到我导入了txjdbcSpring名称空间。这是因为我们将在这个配置文件中大量使用它们。

您要做的第一件事是启用基于注释的事务管理(@Transactional)。人们在Spring中使用Hibernate的主要原因是因为Spring将为您管理所有交易。将以下行添加到配置文件中:

<tx:annotation-driven />

我们需要创建一个数据源。数据源基本上就是Hibernate用来持久化对象的数据库。通常一个事务管理器将有一个数据源。如果您希望Hibernate与多个数据源对话,那么您有多个事务管理器。

数据源的类型将取决于您希望它完成的任务。您可以指定一个现有的数据库,也可以创建一个新的内存中的HSQL/Derby/H2数据库,该数据库由Spring预先打包。就个人而言,当我部署项目进行物理测试时,我有一个Hibernate连接的现有数据库,但我使用内存中的数据库进行单元/集成测试。

我将首先演示如何创建内存中的数据库。

<jdbc:embedded-database id="dataSource" type="HSQL">
    <jdbc:script location="classpath:/setup.sql" />
    .
    .
    .
    <!-- As many scripts can run as you like -->
</jdbc:embedded-database>

上面的配置将创建一个嵌入式(内存中)HSQL数据库作为bean,运行脚本安装程序。sql,然后使数据源bean可用于应用程序上下文。您不必指定数据库类型,因为HSQL是默认值,但我总是想说清楚。设置。sql可以位于类路径中的任何位置(通常是WEB-INF目录)。您可以指定任意数量的SQL脚本。您还可以设置它们是否应在创建或销毁数据库时运行。

这个数据库将与您的应用程序一起生死存亡。不要在生产项目上使用嵌入式数据库,一次停电,所有数据都会消失。

要将数据源连接到现有数据库,配置略有不同。

<bean id="dataSource" 
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="" />
    <property name="url" value="" />
    <property name="username" value="" />
    <property name="password" value="" />
</bean>

这个bean的类可以是实现(我认为)javax.sql.DataSource的任何东西,因此您可以编写自己的。此示例类由Spring提供,但没有自己的线程池。一个流行的替代方案是Apache Commonsorg.apache.commons.dbcp.BasicDataSource,但是还有许多其他的。我将在下面解释每个属性:

>

url:指向数据库的url。通常这类似于jdbc\:oracle\:thin\:\path\to\your\databasejdbc:mysql://path/to/your/database。如果你在谷歌上搜索你正在使用的数据库的默认位置,你应该能够找到它应该是什么。如果您收到带有消息org的HibernateException。冬眠HibernateException:当“hibernate”时,连接不能为null。方言“未设置”如果您遵循本指南,则您的URL错误的概率为90%,数据库未启动的概率为5%,用户名/密码错误的概率为5%。

用户名:使用数据库进行身份验证时使用的用户名。

密码:使用数据库进行身份验证时使用的密码。

接下来的事情,是设置SessionFactory。这是Hibernate用来创建和管理事务,并实际与数据库对话的东西。它有相当多的配置选项,我将在下面尝试解释。

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="au.com.project />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.use_sql_comments">true</prop>
            <prop key="hibernate.hbm2ddl.auto">validate</prop>
        </props>
    </property>
</bean>

>

  • dataSource:您的数据源bean。如果更改了dataSource的ID,请在此处设置。

    PackagesToScan:要扫描以查找JPA注释对象的包。这些是会话工厂需要管理的对象,通常是POJO的,并用@Entity注释。有关如何在Hibernate中设置对象关系的详细信息,请参阅此处。

    AnnotatedClass(未显示):如果Hibernate要扫描的类不在同一个包中,您还可以提供这些类的列表。您应该使用packagesToScanannotatedClass,但不能同时使用两者。声明如下:

    <property name="annotatedClasses">
        <list>
            <value>foo.bar.package.model.Person</value>
            <value>foo.bar.package.model.Thing</value>
        </list>
    </property>
    
    • hibernateProperties:这里有无数的这些都有详细的记录。您将使用的主要工具如下:

    您需要声明的最后两个bean是:

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

    将特定于数据库的HibernateExc0019SQLExceptions转换为应用程序上下文可以理解的Spring异常。

    TransactionManagerbean控制事务和回滚。

    注意:您应该将SessionFactorybean自动连接到DAO中。

    一旦你这样做了。您所要做的就是添加新的数据库servlet。xml到您的web。xml文件。

    <context-param>
    <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/database-servlet.xml
            .
            .
            .
        </param-value>
    </context-param>
    

    这就是让Hibernate真正工作所需的全部内容。您仍然需要向对象添加注释,并向与DAO交互的服务层方法添加@Transactional

    方便的提示:如果您使用的是像Ivy或maven这样的依赖项管理器,并且您在整个Spring都使用它

    所有这些在实践中是如何起作用的

    在服务类中,当您使用@Transactional注释一个方法,然后从其他地方调用该方法时,会发生一些事情。HibernateTransactionManager在调用方法之前使用AOP切入点注入代码。在这里,TransactionManager将执行以下操作(无特定顺序):

    >

    检查现有事务会话的SessionFactory,如果不存在会话,则使用SessionFactory创建一个新会话,具体取决于注释中的参数。

    从这一点开始,事务管理器将记录您对它发现的任何持久对象所做的所有更改,以及在当前会话中运行的任何查询。这样做的目的是,如果抛出异常,那么简单的事情就是回滚自调用该方法以来发生的所有事件。

    SessionFactorybean负责创建、维护、关闭和刷新TransactionManager要求它创建的所有数据库会话。这就是为什么我们将SessionFactory自动连接到DAO中,并通过它运行所有查询。

    新Hibernate用户提出的最大问题之一是“我的更改何时提交?”当您思考TransactionManager如何与SesisonFactory协同工作时,答案是有意义的。退出用@Transactional注释的服务方法时,将刷新并提交数据库更改。这样做的原因是,一个事务应该代表一个完整工作的“单元”。如果单元出现问题,则假定单元出现故障,所有更改都应回滚。因此,当您退出最初调用的服务方法时,SessionFactory将刷新并清除会话。

    这并不是说在事务进行时它也不会刷新和清除会话。例如,如果我调用一个服务方法来添加5个对象的集合并返回数据库中的对象总数,SessionFactory将意识到查询(SELECT count(*))需要一个更新的状态才能准确,因此在运行count查询之前,将刷新添加的5个对象。执行过程可能如下所示:

    //Service
    @Override
    @Transactional
    public long saveAndCount(List<Foo> listOfFoo){
        for(Foo foo : listOfFoo){
            //Doesn't get instantly saved to the database.
            fooDAO.saveOrUpdate(foo);
        }
        /*
         * Before the actual SELECT COUNT(*) query was run, the SessionFactory would
         * flush the save operation of the 5 Foo objects.
         */
        return fooDAO.count();
    }
    

    明确地说,DAO根本没有会话管理代码。它会有一些类似于sesisionFactory.get货币会话(). BuildCriteria(Foo.class);的东西,就是这样。没有操纵会话对象的实例,没有调用flush()Clear()。这就是在Spring中使用Hibernate的好处。

    免责声明:我不知道这些示例是否适用于独立的HIBERNATE

    我与Hibernate或Hibernate开发团队没有任何关系。我提供了这些例子,所以当我回答Hibernate标签上的问题时,我有一个参考点。这些例子和讨论是基于我自己的观点以及我如何使用Hibernate开发我的应用程序。这些例子绝不是全面的。我把它们建立在我过去使用Hibernate的常见情况上。

    如果您在尝试实现这些示例时遇到问题,请不要发表评论,并期望我解决您的问题。学习Hibernate的一部分是学习它的应用编程接口的进出。如果这些例子有错误,请随意编辑。

  •  类似资料:
    • 问题内容: 假设我已经有一个正常的Spring项目,那么在带有Spring 3 XML配置的Hibernate 4中添加所需的最少配置是多少?我想使用基于注释的事务管理,并使用注释映射我的对象。 注意:这是一个自我回答的问答风格问题,旨在为常见问题提供规范的答案。我打算随着时间的推移扩展这个问题,以便与Hibernate保持同步。 问题答案: 我发现将Hibernate与Spring的XML配置结

    • 问题内容: 假设我已经有一个正常的Spring项目,那么在带有Spring 3 XML配置的Hibernate 4中添加所需的最少配置是多少?我想使用基于注释的事务管理,并使用注释映射我的对象。 注意:这是一个自助式问答式问题,旨在为常见问题提供规范的答案。我打算随着时间的推移扩展这个问题,以便与Hibernate保持同步。 问题答案: 我发现在Spring的XML配置中使用Hibernate相当

    • 本文向大家介绍Spring 使用注解方式进行事务管理配置方式,包括了Spring 使用注解方式进行事务管理配置方式的使用技巧和注意事项,需要的朋友参考一下 使用步骤: 步骤一、在spring配置文件中引入<tx:>命名空间 步骤二、具有@Transactional 注解的bean自动配置为声明式事务支持 步骤三、在接口或类的声明处 ,写一个@Transactional. 要是只在接口上写, 接口的

    • 主要内容:1. 开启注解事务,2. 使用 @Transactional 注解,示例 1在《 Spring基于XML实现事务管理》一节中,我们通过 <tx:advice> 元素极大的简化了 Spring 声明式事务所需的 XML 配置。但其实我们还可以通过另一种方式进行进一步的简化,那就是“使用注解实现事务管理”。 在 Spring 中,声明式事务除了可以使用 XML 实现外,还可以使用注解实现,以进一步降低代码之间的耦合度。下面我们就来介绍下,通过注解是如何实现声明式事务管理。 1

    • 问题内容: 在最近我从事的一些大型项目中,选择其中一种(XML或注释)似乎变得越来越重要。随着项目的发展,一致性对于可维护性非常重要。 我的问题是:与基于注释的配置相比,基于XML的配置有哪些优势?与基于XML的配置相比,基于注释的配置有哪些优势? 问题答案: 注释有其用途,但它们不是杀死XML配置的灵丹妙药。我建议将两者混合! 例如,如果使用Spring,则将XML用于应用程序的依赖注入部分是完

    • 我最近的目标是构建一个Spring Boot应用程序,但不需要任何XML配置文件(或尽可能少),因此我希望避免使用一些XML文件(即web.XML),特别是对于一些bean定义部分。 更难的部分来了。 我想使用@AutoWired注释将一个SessionFactory bean注入到类中,但每次尝试启动应用程序时,我都得到: unsatisfiedDependencyException:创建名为“