3

休止状態で postgresql を使用しています。テンプレート テーブルから別のテーブルにデータを一括挿入したいと考えています。ネイティブクエリでそれを行う方法は私には明らかですが、HQL では期待される結果に到達する方法がよくわかりません。http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html#batch-directの構文を使用してクエリを作成しました。

@NamedQuery(name="Tile.bulkLoadLevel", query="INSERT INTO Tile (x, y, game, tileOverlay, startTile, blockWalkable, sightBlocking)" +
        " SELECT t.x, t.y, :game as game, t.tileOverlay, t.startTile, t.blockWalkable, t.sightBlocking from TemplateQuestTile t")

私のシーマ:

CREATE TABLE tile
(
   x integer NOT NULL,
   y integer NOT NULL,
   blockwalkable boolean NOT NULL,
   sightblocking boolean NOT NULL,
   starttile boolean NOT NULL,
   imagepath character varying(255) NOT NULL,
   gameid bigint NOT NULL,
   CONSTRAINT tile_pkey PRIMARY KEY (gameid, x, y)
 );

私のテンプレートを単純化しました:

   CREATE TABLE templatequesttile
   (
     x integer NOT NULL,
     y integer NOT NULL,
     blockwalkable boolean NOT NULL,
     sightblocking boolean NOT NULL,
     starttile boolean NOT NULL,
     imagepath character varying(255) NOT NULL,
     questname character varying(255) NOT NULL,
     CONSTRAINT templatequesttile_pkey PRIMARY KEY (questname, questseries, x, y)
   )

次のエラーが表示されます。

ERROR (SessionFactoryImpl.java:435) - Error in named query: Tile.bulkLoad
org.hibernate.QueryException: number of select types did not match those for insert [INSERT INTO Tile (x, y,    game, tileOverlay, startTile, blockWalkable, sightBlocking) SELECT t.x, t.y, :game, t.tileOverlay, t.startTile, t.blockWalkable, t.sightBlocking from net.hq.model.TemplateQuestTile t]
at org.hibernate.hql.ast.tree.IntoClause.validateTypes(IntoClause.java:115)
at org.hibernate.hql.ast.tree.InsertStatement.validate(InsertStatement.java:57)
at org.hibernate.hql.ast.HqlSqlWalker.postProcessInsert(HqlSqlWalker.java:715)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.insertStatement(HqlSqlBaseWalker.java:519)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:261)

ゲームは、シーケンスによって生成された長い識別子を持つエンティティです。

ご覧のとおり、ゲームはテンプレート テーブルにないため、クエリにゲーム ID を強制する必要があります。これを行う方法を知っている人はいますか?

お時間をいただきありがとうございます。

PS: クエリの呼び出し方法:

Query query = em.createNamedQuery("Tile.bulkLoadLevel");
query.setParameter("game", game.getGameid());
int copyiedEntities = query.executeUpdate();

エンティティ:

public class Tile implements Serializable{

@Id
private int x;
@Id
private int y;
@Id
@ManyToOne
@JoinColumn(name="gameid")
private Game game;

PS: キャストも機能しません。

java.lang.ExceptionInInitializerError の net.hq.process.db.PersistenceTest.setUp(PersistenceTest.java:58) の sun.reflect.NativeMethodAccessorImpl.invoke0(ネイティブ メソッド) の sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ) org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java の java.lang.reflect.Method.invoke(Method.java:597) :44) org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) で org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) で org.junit.internal. org.junit.internal.runners.statements.RunAfters の runners.statements.RunBefores.evaluate(RunBefores.java:27)。evaluate(RunAfters.java:31) で org.junit.runners.ParentRunner.run(ParentRunner.java:236) で org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49) で org .eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) の .internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) org.eclipse.jdt.internal.junit の.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 原因: org の java.lang.Class.forName(Class.java:169) の java.lang.Class.forName0(Native Method) での java.lang.NullPointerException .hibernate.util.ReflectHelper。org.hibernate.type.TypeFactory.heuristicType(TypeFactory.java:279) の classForName(ReflectHelper.java:192) org.hibernate.type.TypeFactory.heuristicType(TypeFactory.java:264) の org.hibernate.hql.ast .util.SessionFactoryHelper.findFunctionReturnType(SessionFactoryHelper.java:400) org.hibernate.hql.ast.util.SessionFactoryHelper.findFunctionReturnType(SessionFactoryHelper.java:392) org.hibernate.hql.ast.tree.MethodNode.dialectFunction(MethodNode) .java:103) で org.hibernate.hql.ast.tree.MethodNode.resolve(MethodNode.java:78) で org.hibernate.hql.ast.HqlSqlWalker.processFunction(HqlSqlWalker.java:979) で org.hibernate. hql.antlr.HqlSqlBaseWalker.functionCall(HqlSqlBaseWalker.java:2529) org.hibernate.hql.antlr.HqlSqlBaseWalker.selectExpr(HqlSqlBaseWalker.java:2129) org.hibernate.hql.antlr.HqlSqlBaseWalker.selectExprList(HqlSqlBaseWalker.java:1983) org.hibernate.hql.antlr.HqlSqlBaseWalker.selectClause(HqlSqlBaseWalker.java:1515) org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker).java:586 org.hibernate.hql.antlr.HqlSqlBaseWalker.insertStatement (HqlSqlBaseWalker.java:510) で org.hibernate.hql.antlr.HqlSqlBaseWalker.statement (HqlSqlBaseWalker.java:261) で(QueryTranslatorImpl.java:254) org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:185) org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136) org.hibernate. engine.query.HQLQueryPlan.(HQLQueryPlan.java:101) at org.hibernate.engine.query.HQLQueryPlan.(HQLQueryPlan.java:80) at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:98) org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:562) org.hibernate.impl.SessionFactoryImpl.(SessionFactoryImpl.java:424) org. hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385) org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954) org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:891) org .hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:57) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32) at net.hq. util.Db.(Db.java:7) ... 17 件以上17以上

4

3 に答える 3

2

試してみてください:

INSERT INTO Tile (x, y, game, tileOverlay, startTile, blockWalkable,sightBlocking) SELECT tx, ty, cast(:game as Game) , t.tileOverlay, t.startTile, t.blockWalkable, t.sightBlocking from TemplateQuestTile t" )

query.setEntity("ゲーム", ゲーム);

Tile という名前のクラスもあり、x、y、tileOverlay... はそのクラスのプロパティであると想定しています。休止状態の参照ドキュメントから:「INSERT ステートメントの疑似構文は次のとおりです: INSERT INTO EntityName properties_list select_statement」。

キャスト関数については、「cast(... as ...)、2 番目の引数は Hibernate 型の名前」なので、動作するはずです。

エンティティでは試していませんが、単純な型 (バイト、整数など) では問題なく動作しました。

于 2011-03-09T19:59:59.063 に答える
1

上記のjorgegmのコメントからこれを行う方法を見つけました.彼の元の答えはNPEを与えるので、これは彼の実際の答えでした.

次のようにクエリを作成します。

INSERT INTO Tile (x, y, game, tileOverlay, startTile, blockWalkable, sightBlocking)
SELECT t.x, t.y, g, t.tileOverlay, t.startTile, t.blockWalkable, t.sightBlocking 
  FROM TemplateQuestTile t,
       Game g
 WHERE g.id = :gameId

次に、電話する

query.setParameter("gameId", game.getId());

Hibernate 3.6 を使用してこれを行いましたが、魅力的に機能します。

于 2013-04-23T18:30:10.367 に答える
-1

このクエリを HQL で表現することはできないと思います。Hibernate のドキュメントではINSERT ... SELECT ...、特にクエリのいくつかの制限について説明しています。

select_statement は任意の有効な HQL 選択クエリにすることができますが、戻り値の型が挿入によって期待される型と一致する必要があることに注意してください。現在、これは、チェックをデータベースに委譲することを許可するのではなく、クエリのコンパイル中にチェックされます。

:gameの型が であるという事実をクエリで表現できないため、Gameこのクエリのコンパイルは決して成功しません。

代わりにネイティブ SQL クエリを使用してみてください。

于 2011-01-20T19:37:39.843 に答える