インプロセスのインメモリHSQLデータベースを使用してスタンドアロンのJavaサービスをセットアップしています。
Persistence.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
Hibernate 3.5.6以降を、HSQLDBバージョン2.2.x以降と一緒に使用する必要があります。それ以外の場合、古いHiberntejarはHSQLDB1.8.xで動作します。テーブルの名前は問題ではありません。私は方言を開発し、このバージョンのHibernateテストを実行しましたが、Pascalは私よりもHibernateの使用法について多くのことを知っており、ここで多くの人々を助けてきました。
私は同じ問題に遭遇し、提供された解決策のどれも(本当に)私を助けませんでした(そしてここに密接に関連しているStackoverflowに関するかなりの数の投稿があります)、しかし私はついにそれを理解しました。したがって、私は自分の調査結果を共有すると思いました(少し長い投稿で申し訳ありません):
私の場合、MySQLデータベースを使用して既存のUnitTestをHSQLDBに変換し、外部の依存関係を削除できるようにしました。次のような説明を見ると、これはすべて簡単に見えます。 http://eskatos.wordpress.com/2007/10/15/unit-test-jpa-entities-with-in-memory-database/ しかし、それはもう少しトリッキーであることが判明しました。
私は実験しました
create
およびifexists
パラメーター(参照: http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html )、しかし、それらのどれも実際には何の違いもありませんでした(エラーはところで異なりました)。 _user lacks privilege or object not found
_エラーメッセージとは別に、私が得ることができた最も有益なメッセージは次のとおりでした:_SQL 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
だから何かが明らかに壊れていた。最大の問題は、次の2つの組み合わせであることが判明しました。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))]
_
したがって、問題は、定義されているBaseEntityに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;
_
そしてすべてがうまくいきます:-)
同様の問題が発生しましたが、私の場合、列の定義が原因で問題が発生しました。私はこのようにMySQL定義を使用しました:
@Id
@GeneratedValue
@Column(columnDefinition = "INT(11)")
private long id;
これはHSQLでサポートされていないようで、定義を次のように変更しました。
@Id
@GeneratedValue
@Column(columnDefinition = "INTEGER")
private long id;
そして、テストは再び機能しました。
上記の投稿のとおり、Hibernate3.5.6をHSQLDB2.0.1と一緒に使用していましたが、それでもエラーがスローされていました。 URLも修正しましたが、役に立ちませんでした。最終的にHQSLjarを1.8.1バージョンに http://sourceforge.net/projects/hsqldb/files/hsqldb/hsqldb_1_8_1/hsqldb_1_8_1_3.Zip/download に変更し、機能しました
参照されているテーブル/シーケンスのSCHEMA名を明示的に指定してみてください。
シーケンスで認識されないという同様の問題に直面したところ、Hibernate @ SequenceGeneratorアノテーションでスキーマのプレフィックスをシーケンス参照に付けていないことに気付きました。
call next value for EXAMPLE_SCHEMA.TEST_SEQ
HSQLはlongtext
ではなく、LONGVARCHAR
型を使用します。それを変更すると、必要な特権について不平を言うという私にとっても同様の問題が解決しました。
このエラーが発生したとき、_persistence.xml
_で間違ったプロバイダークラスを使用していることに気付きました。
Hibernateの場合は
_<provider>org.hibernate.ejb.HibernatePersistence</provider>
_
そしてEclipseLinkの場合は
_<provider>org.Eclipse.persistence.jpa.PersistenceProvider</provider>
_
また、_persistence.xml
_とPersistence.createEntityManagerFactory("name")
の作成時に異なる名前が使用されることに注意してください。
私も同じエラーに直面しました。 「connection.url」でスクリプトファイルの絶対パスを指定すると解決しました。
<property name = "connection.url"> jdbc:hsqldb:file:C:\ Hibernate-example\database\mydb; shutdown = true </ property>