我刚刚开始使用 Hibernate 并开始思考问题。
目前我正在尝试设置一个测试环境,我可以在其中使用 HSQL 内存实例来测试我的项目。
我遇到的错误是:
javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: invalid schema name: TSG
以下是我项目的相关部分:
持久性.xml
<?xml version="1.0" encoding="UTF-8"?>
org.hibernate.ejb.HibernatePersistence com.foo.api.models.tsg.AlgPpcAlgorithmOutputEntity
<persistence-unit name="TestingPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.foo.api.models.tsg.AlgPpcAlgorithmOutputEntity
</class>
<properties>
<property name="dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:tsg"/>
<property name="hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.connection.autocommit" value="true"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
如您所见,我有一个peristence-unit
用于生产(工作正常)和一个内存中的 HSQL 一个用于测试(我无法开始工作)。
一个示例 Hibernate 实体:
package com.foo.api.models.tsg;
import javax.persistence.*;
import java.math.BigDecimal;
@IdClass(AlgPpcAlgorithmOutputEntityPK.class)
@Table(name = "alg_ppc_algorithm_output", schema = "", catalog = "tsg")
@Entity
public class AlgPpcAlgorithmOutputEntity {
private int parameterId;
@Column(name = "parameter_id")
@Id
public int getParameterId() {
return parameterId;
}
public void setParameterId(int parameterId) {
this.parameterId = parameterId;
}
private String matchType;
@Column(name = "matchType")
@Basic
public String getMatchType() {
return matchType;
}
// for brevity I have removed the rest of the implementation
// It was auto-generated by Hibernate and works fine in production.
}
最后,一个简单的 TestCase 类:
package tests.integration;
import com.foo.api.models.tsg.AlgPpcAlgorithmOutputEntity;
import com.foo.api.util.HibernateUtil;
import org.hsqldb.Server;
import org.hsqldb.persist.HsqlProperties;
import org.hsqldb.server.ServerConfiguration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tests.util.HSQLServerUtil;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import com.foo.api.KeywordManager;
import java.sql.Date;
import java.util.HashSet;
public class KeywordManagerTestCase {
private static final Logger LOG = LoggerFactory.getLogger(KeywordManagerTestCase.class);
private EntityManagerFactory eMF;
protected EntityManager eM;
@Before
public void setUp() throws Exception {
HsqlProperties props = new HsqlProperties();
props.setProperty("server.database.0", "mem:tsg");
props.setProperty("server.dbname.0", "tsg");
ServerConfiguration.translateDefaultDatabaseProperty(props);
Server hsqlServer = new Server();
hsqlServer.setRestartOnShutdown(false);
hsqlServer.setNoSystemExit(true);
hsqlServer.setProperties(props);
hsqlServer.setTrace(true);
LOG.info("Configured the HSQLDB server...");
hsqlServer.start();
LOG.info("HSQLDB server started on port " + hsqlServer.getPort() + "...");
LOG.info("Loading hibernate...");
if (eMF == null) {
eMF = Persistence.createEntityManagerFactory("TestingPersistenceUnit");
}
eM = eMF.createEntityManager();
}
/**
* shutdown the server.
* @throws Exception in case of errors.
*/
@After
public void tearDown() throws Exception {
eM.close();
HSQLServerUtil.getInstance().stop();
}
/**
* Demo test to see that the number of user records in the database corresponds the flat file inserts.
*/
@Test
public void testDemo1() {
AlgPpcAlgorithmOutputEntity entity = new AlgPpcAlgorithmOutputEntity();
entity.setParameterId(200);
entity.setMatchType("aa");
KeywordManager km;
eM.persist(entity);
HashSet<Integer> params = new HashSet<Integer>();
params.add(200);
km = new KeywordManager(eM, params, new Date[2]);
HashSet<AlgPpcAlgorithmOutputEntity> res = km.pullKeywords(params);
for (AlgPpcAlgorithmOutputEntity s : res) {
System.out.println(s.getMatchType());
}
}
}
我确信我已经以一种奇怪的方式设置了一些东西,但正如我所说 - 这是我的第一次刺伤。
这是我正在尝试做的事情:
- 在 persistence.xml 中包含 HSQL 数据库的测试配置(以及所有休眠类映射)
- 让 HSQL db 开始进行单元测试,并使用我的项目模式创建内存数据库(如类元素下的 persistence.xml 中所述)。
- 创建实体对象并在测试时将它们添加到测试数据库,以便我可以将数据库用于我的集成测试。
我就是无法通过这个 PersistenceException!
更新
好的,所以我意识到我不需要在我的测试用例设置中设置显式 HSQL 服务器,因为这正是我的persistence-unit
条目的persistence.xml
用途。我还尝试更改 CATALOG 以使其与我的映射类使用的目录相匹配。我的测试用例的设置现在看起来像:
private EntityManagerFactory eMF;
protected EntityManager eM;
@Before
public void setUp() throws Exception {
LOG.info("Loading hibernate...");
if (eMF == null) {
eMF = Persistence.createEntityManagerFactory("TestingPersistenceUnit");
}
eM = eMF.createEntityManager();
EntityTransaction eT = null;
eT = eM.getTransaction();
eT.begin();
Query q = eM.createNativeQuery("ALTER CATALOG PUBLIC RENAME TO TSG");
q.executeUpdate();
eT.commit();
// And also it seems I need to create the schema
eT = eM.getTransaction();
eT.begin();
q = eM.createNativeQuery("CREATE SCHEMA TSG AUTHORIZATION DBA");
q.executeUpdate();
eT.commit();
}
但是,我现在遇到了一个新错误,特别是:
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: user lacks privilege or object not found: ALG_PPC_ALGORITHM_OUTPUT
所以我到了某个地方,但似乎没有创建表。请问是不是我的有问题persistence.xml
?