Spring Data JPA xml配置:使用create-drop创建“找不到表”

时间:2014-09-02 20:49:20

标签: java spring spring-data-jpa

我可能在某处忘记了某些东西,我无法弄清楚是什么。

我有一个@Entity:

@Entity
public class MyEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Long id;

我有一个JpaRepository

public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {

}

这是我的appContext.xml

<!-- CORE -->
<context:annotation-config />
<context:component-scan base-package="com.foo.project" />

<!-- WEB -->
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/" />

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/pages/" />
  <property name="suffix" value=".jsp" />
</bean>

<!-- DATA -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="org.h2.Driver" />
  <property name="url" value="jdbc:h2:mem:test" />
  <property name="username" value="sa" />
  <property name="password" value="" />
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="packagesToScan" value="com.foo.project.domain" />
  <property name="jpaVendorAdapter">
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
  </property>
  <property name="jpaProperties">
    <props>
      <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
      <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
    </props>
  </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<tx:annotation-driven />

<jpa:repositories base-package="com.foo.project.repository" />

我有一个单元测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:**/appContext.xml" })
public class MyEntityRepositoryTest {
    @Autowired private MyEntityRepository myEntityRepository;

当我运行测试时,我收到错误:

  

错误:表&#34; MYENTITY&#34;没找到;

这是完整的日志:

sept. 04, 2014 8:19:47 AM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [
    name: default
    ...]
sept. 04, 2014 8:19:47 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.6.Final}
sept. 04, 2014 8:19:47 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
sept. 04, 2014 8:19:47 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
sept. 04, 2014 8:19:48 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
sept. 04, 2014 8:19:48 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
sept. 04, 2014 8:19:49 AM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
sept. 04, 2014 8:19:49 AM org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 5.1.2.Final
sept. 04, 2014 8:19:50 AM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000227: Running hbm2ddl schema export
sept. 04, 2014 8:19:50 AM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete
sept. 04, 2014 8:19:52 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 42102, SQLState: 42S02
sept. 04, 2014 8:19:52 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Table "MYENTITY" not found; SQL statement:
select count(*) as col_0_0_ from MyEntity myEntity0_ [42102-181]

我错过了什么?

3 个答案:

答案 0 :(得分:7)

您有以下配置

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.h2.Driver" />
    <property name="url" value="jdbc:h2:mem:test" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean

此配置的问题在于,启动时Hibernate将打开一个连接并创建数据库并关闭连接。在连接关闭时,数据库将被销毁,一旦您开始测试,数据库就会再次为空。

您的问题有3个解决方案

  1. 使用Spring嵌入式数据库标记
  2. 将DB_CLOSE_DELAY = -1添加到您的网址
  3. 使用SingleConnectionDataSource
  4. 嵌入式数据库

    使用embedded-database命名空间中的jdbc标记替换您的数据源定义。

    <jdbc:embedded-database id="dataSource" type="H2" />
    

    添加了DB_CLOSE_DELAY

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.h2.Driver" />
        <property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1" />
        <property name="username" value="sa" />
        <property name="password" value="" />
    </bean
    

    使用SingleConnectionDataSource

    <bean id="dataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
        <constructor-arg index="0" value="org.h2.Driver" />
        <constructor-arg index="1" value="jdbc:h2:mem:test" />
        <constructor-arg index="2" value="sa" />
        <constructor-arg index="3" value="" />
        <constructor-arg index="4" value="true"/>
    </bean>
    

    这将打开一个Connection并将其重复用于所有其他调用,因为它会禁止关闭连接。

    这些选项中的任何一个都会使数据库保持活跃状态​​。选项1和2基本相同,EmbeddedDatabaseBuilder使用包含上述属性的jdbc URL。

答案 1 :(得分:2)

(刚刚测试过):使用jdbc:embedded-database元素,而不是普通的bean元素。您需要jdbc命名空间

<xmlns:jdbc="http://www.springframework.org/schema/jdbc">
<xsi:schemaLocation="http://www.springframework.org/schema/jdbc           
                  http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd">

<!-- ... -->

<jdbc:embedded-database id="dataSource" type="H2">
</jdbc:embedded-database>

<!-- DATA  ========= get rid of this =================
<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.h2.Driver" />
    <property name="url" value="jdbc:h2:mem:test" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean>
-->

我真的没有很好的解释(或任何):-),我知道它有效。当我有机会的时候,我会深入挖掘这个。

答案 2 :(得分:0)

您的实体不需要指定基于它的表吗?

@Table(name = "MYENTITY")

一些文档(参见章节2.2.1.1。定义表格):

  

http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#entity-mapping-entity