hibernate复合键hql插入批量

时间:2014-07-30 14:36:33

标签: java sql hibernate jpa

我在现有数据库中有复合键的表。当我想在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?

1 个答案:

答案 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