我在现有数据库中有复合键的表。当我想在HQL中使用批量插入时,如" INSERT INTO entityName(id.key1 id.key2,property1,property,...)SELECT prop1,prop2,prop3,prop3 FROM entityName2"我收到错误:引起:org.hibernate.QueryException:无法解析属性...
如果我的"插入" -statement的实体只有一个id-column,那么一切都像魅力一样。
我使用hibernate-entitymanager版本4.3.6。
首先是insert-clause的实体:
package de.kbv.rms;
// Generated 30.07.2014 10:31:56 by Hibernate Tools 4.3.1
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
* Dm1Dap generated by hbm2java
*/
@Entity
@Table(name="DM1_DAP"
)
public class Dm1Dap implements java.io.Serializable {
@EmbeddedId
@AttributeOverrides( {
@AttributeOverride(name="dmpFallNr", column=@Column(name="DMP_FALL_NR", nullable=false, length=10) ),
@AttributeOverride(name="anr", column=@Column(name="ANR", nullable=false, length=14) ),
@AttributeOverride(name="versNr", column=@Column(name="VERS_NR", nullable=false, length=21) ),
@AttributeOverride(name="kassenNr", column=@Column(name="KASSEN_NR", nullable=false, length=10) ) } )
private Dm1DapId id;
// ... columns with getters and setters.
DAP-Entity的复合键:
package de.kbv.rms;
// Generated 30.07.2014 10:31:56 by Hibernate Tools 4.3.1
import javax.persistence.Column;
import javax.persistence.Embeddable;
/**
* Dm1DapId generated by hbm2java
*/
@Embeddable
public class Dm1DapId implements java.io.Serializable {
@Column(name="DMP_FALL_NR", nullable=false, length=10)
private String dmpFallNr;
@Column(name="ANR", nullable=false, length=14)
private String anr;
@Column(name="VERS_NR", nullable=false, length=21)
private String versNr;
@Column(name="KASSEN_NR", nullable=false, length=10)
private String kassenNr;
// columns with getters and setters
...
// equals and hash-Methods
...
我的select-clause实体。我分别测试了select-clause,它没有问题。
package de.kbv.rms;
// Generated 30.07.2014 10:31:56 by Hibernate Tools 4.3.1
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
* Dm1F generated by hbm2java
*/
@Entity
@Table(name="DM1_F"
)
public class Dm1F implements java.io.Serializable {
@EmbeddedId
@AttributeOverrides( {
@AttributeOverride(name="DmpFallNr", column=@Column(name="F_DMP_FALL_NR", nullable=false, length=10) ),
@AttributeOverride(name="Anr", column=@Column(name="F_ANR", nullable=false, length=14) ),
@AttributeOverride(name="DokuDatum", column=@Column(name="F_DOKU_DATUM", nullable=false, length=7) ) } )
private Dm1FId id;
// ... columns with getters and setters.
我的Dm1F-Entity的复合键:
package de.kbv.rms;
// Generated 30.07.2014 10:31:56 by Hibernate Tools 4.3.1
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
* Dm1FId generated by hbm2java
*/
@Embeddable
public class Dm1FId implements java.io.Serializable {
@Column(name="F_DMP_FALL_NR", nullable=false, length=10)
private String DmpFallNr;
@Column(name="F_ANR", nullable=false, length=14)
private String Anr;
@Temporal (TemporalType.DATE)
@Column(name="F_DOKU_DATUM", nullable=false, length=7)
private Date DokuDatum;
// columns with getters and setters
...
// equals and hash-Methods
...
我的JUNIT-Test:
package dao.test;
import java.util.concurrent.TimeUnit;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.persistence.Query;
import org.junit.Test;
public class RmsSimpleTest {
public static EntityManager entityManager = Persistence.createEntityManagerFactory("devsample")
.createEntityManager();
@Test
public void testQuery() {
long startTime = System.nanoTime();
Query query = entityManager
.createQuery("INSERT INTO Dm1Dap (id.dmpFallNr, id.anr, id.versNr, id.kassenNr) SELECT f.id.DmpFallNr, f.id.Anr, f.VersNr, f.KassenNr FROM Dm1F f");
query.executeUpdate();
long estimatedTime = java.lang.System.nanoTime() - startTime;
System.out.println(" Time: "
+ String.format("%d milsec", TimeUnit.NANOSECONDS.toMillis(estimatedTime)));
}
}
stacktrace片段:
java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: of: de.kbv.rms.Dm1Dap [INSERT INTO Dm1Dap (id.dmpFallNr, id.anr, id.versNr, id.kassenNr) SELECT f.id.DmpFallNr, f.id.Anr, f.VersNr, f.KassenNr FROM de.kbv.rms.Dm1F f]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750)
DEBUG-段:
4016 [main] DEBUG org.hibernate.hql.internal.ast.QueryTranslatorImpl - parse() - HQL: INSERT INTO Dm1Dap (id.dmpFallNr, id.anr, id.versNr, id.kassenNr) SELECT f.id.DmpFallNr, f.id.Anr, f.VersNr, f.KassenNr FROM de.kbv.rms.Dm1F f
4038 [main] DEBUG org.hibernate.hql.internal.ast.QueryTranslatorImpl - --- HQL AST ---
\-[INSERT] Node: 'INSERT'
+-[INTO] Node: 'INTO'
| +-[IDENT] Node: 'Dm1Dap'
| \-[RANGE] Node: 'column-spec'
| +-[DOT] Node: '.'
| | +-[IDENT] Node: 'id'
| | \-[IDENT] Node: 'dmpFallNr'
| +-[DOT] Node: '.'
| | +-[IDENT] Node: 'id'
| | \-[IDENT] Node: 'anr'
| +-[DOT] Node: '.'
| | +-[IDENT] Node: 'id'
| | \-[IDENT] Node: 'versNr'
| \-[DOT] Node: '.'
| +-[IDENT] Node: 'id'
| \-[IDENT] Node: 'kassenNr'
\-[QUERY] Node: 'query'
\-[SELECT_FROM] Node: 'SELECT_FROM'
+-[FROM] Node: 'FROM'
| \-[RANGE] Node: 'RANGE'
| +-[DOT] Node: '.'
| | +-[DOT] Node: '.'
| | | +-[DOT] Node: '.'
| | | | +-[IDENT] Node: 'de'
| | | | \-[IDENT] Node: 'kbv'
| | | \-[IDENT] Node: 'rms'
| | \-[IDENT] Node: 'Dm1F'
| \-[ALIAS] Node: 'f'
\-[SELECT] Node: 'SELECT'
+-[DOT] Node: '.'
| +-[DOT] Node: '.'
| | +-[IDENT] Node: 'f'
| | \-[IDENT] Node: 'id'
| \-[IDENT] Node: 'DmpFallNr'
+-[DOT] Node: '.'
| +-[DOT] Node: '.'
| | +-[IDENT] Node: 'f'
| | \-[IDENT] Node: 'id'
| \-[IDENT] Node: 'Anr'
+-[DOT] Node: '.'
| +-[IDENT] Node: 'f'
| \-[IDENT] Node: 'VersNr'
\-[DOT] Node: '.'
+-[IDENT] Node: 'f'
\-[IDENT] Node: 'KassenNr'
4038 [main] DEBUG org.hibernate.hql.internal.ast.ErrorCounter - throwQueryException() : no errors
4065 [main] DEBUG org.hibernate.hql.internal.antlr.HqlSqlBaseWalker - insert << begin [level=1, statement=insert]
4071 [main] ERROR org.hibernate.hql.internal.ast.ErrorCounter - <AST>:1:24: unexpected AST node: .
4071 [main] ERROR org.hibernate.hql.internal.ast.ErrorCounter - <AST>:1:24: unexpected AST node: .
<AST>:1:24: unexpected AST node: .
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.insertablePropertySpec(HqlSqlBaseWalker.java:986)
有没有办法在hibernate中使用bulk-insert和composite-key?
答案 0 :(得分:0)
作为一种变通方法,您应该将composite-id属性直接添加到实体并将其设置为insertable = false and updateable = false
。无需为该属性添加getter / setter。
@Column(name = "F_DMP_FALL_NR", insertable = false, updateable = false)
private String DmpFallNr;
插入select 批量操作不会检查此选项。现在,您可以删除id前缀并直接在HQL查询中使用这些属性。
INSERT INTO Dm1Dap (idmpFallNr, anr, versNr, kassenNr) SELECT f.id.DmpFallNr, f.id.Anr, f.VersNr, f.KassenNr FROM Dm1F f