2014-05-02 255 views
0

我想要使用JPA/EclipseLink 2.4.1和MSSQL服务器使用Merlia驱动程序执行批量持久化。基于数据库与日志(下图)一起反应的方式,每个插入看起来都发生在其自己的批次中。JPA批量更新似乎是插入每批更新

我已经设置了持久性的XML,如下所示:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> 
    <persistence-unit name="EclipseLinkPersistenceUnit"> 
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
    <class>com.mypackage.ViewInDatabaseEntity</class> 
    ... 
    <exclude-unlisted-classes>true</exclude-unlisted-classes> 
    <properties> 
     <property name="javax.persistence.jdbc.driver" value="com.inet.tds.PDataSource4"/> 
     <property name="eclipselink.jdbc.batch-writing" value="jdbc" /> 
     <property name="eclipselink.jdbc.batch-writing.size" value="1000" /> 
     <property name="eclipselink.logging.level" value="FINEST"/> 
    </properties> 
    </persistence-unit> 
</persistence> 

代码调用坚持这个样子的。我通常使用@Transactional,但决定手动开始和提交事务,以确保注释不会在底层做一些意想不到的事情。

//@Transactional 
    public void persistEntity(List<ViewInDatabaseEntity> entitiesToPersist) { 
    EntityManager entityManager = entityManagerProvider.get(); 
    entityManager.setFlushMode(FlushModeType.COMMIT); 
    EntityTransaction transaction = entityManager.getTransaction(); 
    transaction.begin(); 

    for (ViewInDatabaseEntity entity : entitiesToPersist) { 
     entityManager.persist(entity); 
    } 

    transaction.commit(); 
    } 

日志(设置为FINEST)的输出:

[EL Finer]: transaction: 2014-05-02 16:42:49.963--ClientSession(27801544)--Connection(28732068)--Thread(Thread[qtp18824904-22,5,main])--begin transaction 
... 
[EL Finest]: query: 2014-05-02 16:42:49.964--ClientSession(27801544)--Thread(Thread[qtp18824904-22,5,main])--Execute query ValueReadQuery(name="SEQ_GEN_SEQUENCE" sql="SELECT @@IDENTITY") 
[EL Finer]: sql: 2014-05-02 16:42:56.422--ClientSession(27801544)--Connection(28732068)--Thread(Thread[qtp18824904-22,5,main])--Begin batch statements 
[EL Fine]: sql: 2014-05-02 16:42:56.422--ClientSession(27801544)--Connection(28732068)--Thread(Thread[qtp18824904-22,5,main])--INSERT INTO dbo.ViewInDatabaseEntity(property1, property4, property3, property2, property5) VALUES (?, ?, ?, ?, ?) 
[EL Fine]: sql: 2014-05-02 16:42:56.422--ClientSession(27801544)--Connection(28732068)--Thread(Thread[qtp18824904-22,5,main])-- bind => [ABC, DEF, GHI, JKL, 0.3465443] 
[EL Finer]: sql: 2014-05-02 16:42:56.422--ClientSession(27801544)--Connection(28732068)--Thread(Thread[qtp18824904-22,5,main])--End Batch Statements 
[EL Fine]: sql: 2014-05-02 16:42:56.505--ClientSession(27801544)--Connection(28732068)--Thread(Thread[qtp18824904-22,5,main])--SELECT @@IDENTITY 
[EL Finest]: sequencing: 2014-05-02 16:42:56.506--UnitOfWork(15091453)--Thread(Thread[qtp18824904-22,5,main])--assign sequence to the object (89,588 -> [email protected]) 
[EL Finest]: query: 2014-05-02 16:42:56.507--UnitOfWork(15091453)--Thread(Thread[qtp18824904-22,5,main])--Execute query InsertObjectQuery([email protected]) 
[EL Finest]: query: 2014-05-02 16:42:56.507--ClientSession(27801544)--Thread(Thread[qtp18824904-22,5,main])--Execute query ValueReadQuery(name="SEQ_GEN_SEQUENCE" sql="SELECT @@IDENTITY") 
[EL Finer]: sql: 2014-05-02 16:42:56.507--ClientSession(27801544)--Connection(28732068)--Thread(Thread[qtp18824904-22,5,main])--Begin batch statements 
[EL Fine]: sql: 2014-05-02 16:42:56.507--ClientSession(27801544)--Connection(28732068)--Thread(Thread[qtp18824904-22,5,main])--INSERT INTO dbo.ViewInDatabaseEntity(property1, property4, property3, property2, property5) VALUES (?, ?, ?, ?, ?) 
[EL Fine]: sql: 2014-05-02 16:42:56.507--ClientSession(27801544)--Connection(28732068)--Thread(Thread[qtp18824904-22,5,main])-- bind => [ABC, ZYX, WVU, RST, 0.35345634] 
[EL Finer]: sql: 2014-05-02 16:42:56.507--ClientSession(27801544)--Connection(28732068)--Thread(Thread[qtp18824904-22,5,main])--End Batch Statements 
[EL Fine]: sql: 2014-05-02 16:42:56.591--ClientSession(27801544)--Connection(28732068)--Thread(Thread[qtp18824904-22,5,main])--SELECT @@IDENTITY 
[EL Finest]: sequencing: 2014-05-02 16:42:56.592--UnitOfWork(15091453)--Thread(Thread[qtp18824904-22,5,main])--assign sequence to the object (89,666 -> [email protected]) 
... 
[EL Finer]: transaction: 2014-05-02 16:42:56.598--ClientSession(27801544)--Connection(28732068)--Thread(Thread[qtp18824904-22,5,main])--commit transaction 
[EL Finest]: connection: 2014-05-02 16:42:56.605--ServerSession(2644459)--Connection(28732068)--Thread(Thread[qtp18824904-22,5,main])--Connection released to connection pool [default]. 

这似乎表明,每个刀片的是它自己的批次内发生的事情。根据persistence.xml;我已启用

<property name="eclipselink.jdbc.batch-writing" value="jdbc" /> 

因此,据我所知,这些插入应作为批处理发生。 以下是我试图坚持的实体。它作为一个视图覆盖MSSQL Server数据库中的几个基础表。

@javax.persistence.Table(name = "ViewInDatabase", schema = "dbo") 
@Entity 
@EqualsAndHashCode 
@Getter 
@Setter 
public class ViewInDatabaseEntity { 

    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE) 
    private int id; 

    @javax.persistence.Column(name = "id", nullable = false, insertable = false, updatable = false, 
     length = 0, precision = 0) 
    @Basic 
    public int getId() { 
    return id; 
    } 

    @javax.persistence.Column(name = "property1", nullable = false, insertable = true, 
     updatable = true, length = 20, precision = 0) 
    @Basic 
    private String property1; 

    @javax.persistence.Column(name = "property2", nullable = true, insertable = true, updatable = true, 
     length = 0, precision = 0) 
    @Basic 
    private String property2; 

    @javax.persistence.Column(name = "property3", nullable = true, insertable = true, 
     updatable = true, length = 0, precision = 0) 
    @Basic 
    private String property3; 

    @javax.persistence.Column(name = "property4", nullable = false, insertable = true, updatable = true, 
     length = 10, precision = 0) 
    @Basic 
    private String property4; 

    @javax.persistence.Column(name = "property5", nullable = true, insertable = true, updatable = true, 
     length = 0, precision = 0) 
    @Basic 
    private BigDecimal property5; 

    @javax.persistence.Column(name = "property6", nullable = false, insertable = false, 
     updatable = false, length = 0, precision = 0) 
    @Basic 
    private int property6; 

    @javax.persistence.Column(name = "property7", nullable = false, insertable = false, 
     updatable = false, length = 0, precision = 0) 
    @Basic 
    private Date property7; 
} 

回答

1

当序列策略需要在每个插入语句后查找指定的序列值时,批次将不起作用。尝试使用表排序或一些策略,允许预先分配序列值,以便可以批处理。