内部 HSQL 数据库抱怨权限

2022-09-04 06:26:46

我正在设置一个独立的Java服务,其中包含一个进程内内存中的HSQL数据库。

持久性.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
 version="2.0">

 <persistence-unit name="manager">

 <class>tr.silvercar.data.entities.User</class>
 <properties>
 <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" />
 <property name="javax.persistence.jdbc.user" value="sa" />
 <property name="javax.persistence.jdbc.password" value="" />
 <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:testdb" />

 <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
 <property name="hibernate.max_fetch_depth" value="3" />

 <!-- cache configuration -->
<!-- 
 <property name="hibernate.ejb.classcache.org.hibernate.ejb.test.Item"
  value="read-write" />
 <property
  name="hibernate.ejb.collectioncache.org.hibernate.ejb.test.Item.distributors"
  value="read-write, RegionName" />
 -->
 </properties>

 </persistence-unit>

</persistence>

法典

  emf = Persistence.createEntityManagerFactory("manager");

  User newUser = new User();
  newUser.setName("Testgebruiker");
  newUser.setCredits(100);

  System.out.println("Inserting user");
  EntityManager em = emf.createEntityManager();
  em.persist(newUser);
  em.close();

  System.out.println("Getting user");
  em = emf.createEntityManager();
  User u = (User) em.createQuery("SELECT u FROM User u").getSingleResult();
  em.close();
  System.out.println(u);

在我看来,由于数据库在内存中,而Hibernate应该生成表,因此我不需要执行任何其他操作。但是,在调用时,我得到异常:getSingleResult

org.hsqldb.HsqlException: user lacks privilege or object not found: USER

答案 1

您需要使用Hibernate 3.5.6或更高版本,以及HSQLDB版本2.2.x或更高版本。否则,较旧的Hibernte jar可以与HSQLDB 1.8.x一起使用。表的名称不是问题。我已经开发了方言并为此版本运行了Hibernate测试,但是Pascal比我更了解Hibernate的用法,并且帮助了很多人。


答案 2

我遇到了同样的问题,没有提供任何解决方案(真的)帮助我(而且Stackoverflow上还有相当多的帖子密切相关),但我终于弄清楚了。因此,我想我分享了我的发现(抱歉这篇文章有点冗长):

在我的例子中,我使用MySQL数据库将一些现有的UnitTests转换为HSQLDB,以便可以删除外部依赖项。如果你看一下这样的描述,这一切看起来都很容易:http://eskatos.wordpress.com/2007/10/15/unit-test-jpa-entities-with-in-memory-database/ 但事实证明它有点棘手。

我尝试了

  1. 不同的版本(如上所述),
  2. 和 参数(请参见:http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html),createifexists
  3. 指定不同的用户凭据(用户名=“sa”,密码=“”是正确的),
  4. 将 update、 create 和 create-drop 指定为 hibernate.hbm2ddl.auto(参见 http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html),
  5. 使用不同类型的数据源:c3p0,dbcp,...
  6. ...

但这些都没有真正产生任何影响(顺便说一句,错误不同)。除了错误消息之外,我能得到的最有信息量的一个是以下内容:(这转化为“驱动程序不支持此功能”)更明确地,我在日志中发现了这一点:user lacks privilege or object not foundSQL Error: -20, SQLState: IM001[2012-09-24 14:50:45,796] ERROR main::org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions(144) | This function is not supported

所以有些东西显然坏了。事实证明,最大的问题是两件事的组合:1.我没有正确查看日志输出,因为它实际上包含线索2。错误的注释

关于1:

问题在于输出包含大量如下所示的行(显然可以忽略,甚至还有 H2 的票证):

[2012-09-25 10:07:13,453] ERROR main::org.hibernate.tool.hbm2ddl.SchemaExport.perform(426) | HHH000389: Unsuccessful: alter table SimpleSubscription drop constraint FKAD76A00F168752B2
[2012-09-25 10:07:13,453] ERROR main::org.hibernate.tool.hbm2ddl.SchemaExport.perform(427) | user lacks privilege or object not found: PUBLIC.SIMPLESUBSCRIPTION
Hibernate: alter table SimpleSubscriptionChange drop constraint FKB3B8189FFC3506ED
[2012-09-25 10:07:13,453] ERROR main::org.hibernate.tool.hbm2ddl.SchemaExport.perform(426) | HHH000389: Unsuccessful: alter table SimpleSubscriptionChange drop constraint FKB3B8189FFC3506ED
[2012-09-25 10:07:13,453] ERROR main::org.hibernate.tool.hbm2ddl.SchemaExport.perform(427) | user lacks privilege or object not found: PUBLIC.SIMPLESUBSCRIPTIONCHANGE
Hibernate: alter table SimpleSubscriptionChange_languages drop constraint FK5A45F07BFC21A8E6

关于2:

在所有这些行之间隐藏了以下行,这实际上给出了错误是什么:

[2012-09-25 10:07:13,468] ERROR main::org.hibernate.tool.hbm2ddl.SchemaExport.perform(426) | HHH000389: Unsuccessful: create table Rule (id bigint generated by default as identity (start with 1), creationTime timestamp not null, deleted BIT not null, lastUpdateTime timestamp, version integer not null, fetcher varchar(255), hash integer not null, primary key (id), unique (id))
[2012-09-25 10:07:13,468] ERROR main::org.hibernate.tool.hbm2ddl.SchemaExport.perform(427) | a UNIQUE constraint already exists on the set of columns in statement [create table Rule (id bigint generated by default as identity (start with 1), creationTime timestamp not null, deleted BIT not null, lastUpdateTime timestamp, version integer not null, fetcher varchar(255), hash integer not null, primary key (id), unique (id))]

因此,问题在于定义的基本实体对 id 具有错误的注释:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(nullable = false, unique = true)
private Long id;

该字段已被标识为ID(即主键),因此不能具有唯一的注释(并且也是多余的)。将其更改为:nullable

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;

一切都很好:-)


推荐