JPA:预分配ID块不能正常工作

时间:2014-04-23 11:35:58

标签: jpa eclipselink

我试图通过注释@TableGenerator管理ID生成,并使用allocationSize默认值。据我了解,为避免为请求的每个标识符更新行,使用分配大小。理论上,提供者应该预先分配一个标识符块,在这种情况下等于allocationSize - 50的值 - 然后根据请求从内存中提供标识符,直到块用完或事务结束。

我在JBoss 7.1中使用Eclipselink(EL)。

问题是这不会发生。在表格中插入3条记录学生,EL预先为每条记录分配一个50个ID的块,即使该事务是相同的。然后,对于每条记录,始终可以访问该表。从日志中我看到3个预分配和3对选择/更新查询ID和ID生成1-51 -101,序列的最终值为150.日志片段

Connection acquired from connection pool
UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?
bind => [50, TABLE_SEQ]
SELECT SEQ_COUNT FROM SEQUENCE WHERE SEQ_NAME = ?
bind => [TABLE_SEQ]
local sequencing preallocation for TABLE_SEQ: objects: 50 , first: 1, last: 50
Connection released to connection pool [default].

Connection acquired from connection pool
UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?
bind => [50, TABLE_SEQ]
SELECT SEQ_COUNT FROM SEQUENCE WHERE SEQ_NAME = ?
bind => [TABLE_SEQ]
local sequencing preallocation for TABLE_SEQ: objects: 50 , first: 51, last: 100
Connection released to connection pool [default].

作为单个事务,我期望顺序ID(1-2-3)和序列50的最终值。 我哪里错了?我试图在论坛上做研究,但我甚至无法解决问题。 下面是简单的测试代码。 谢谢你的帮助。

实体学生

@Entity
@Table(name="STUDENTS")
public class Student implements Serializable
{
    private static final long serialVersionUID = 4771385985502937621L;

    @TableGenerator(name="TABLE_SEQ")
    @Id @Column(name="ID_STUDENT") @GeneratedValue(generator="TABLE_SEQ")
    private int idStudent;

    private String name;

    public int getIdStudent() {
        return idStudent;
    }

    public void setIdStudent(int idStudent) {
        this.idStudent = idStudent;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name= name;
    }
}

EJB

@Stateless(name="EJBStudent")
public class EJBStudent implements EJBStudentRemote
{
    @PersistenceContext(unitName="JPA_Test")
    private EntityManager manager;

    public EJBStudent() {
    }


    @Override
    public void insertStudents() 
    {
        manager.getTransaction().begin();

        Student student1 = new Student();
        student1.setName("Anna");
        manager.persist(student1);

        Student student2 = new Student();
        student2.setName("Paolo");
        manager.persist(student2);

            Student student3 = new Student();
        student3.setName("Luigi");
        manager.persist(student3);

        manager.flush();
    }
}

修改 @Chris感谢您的回复。

这是最好的日志。我只注意到一个主要的区别。对于每个插入,它会创建不同的连接。但是,如果首先运行@wypieprz建议的查询,则连接始终是相同的。

Invoking org.jboss.invocation.InterceptorContext$Invocation.insertStudent    
[EL Finer]: connection: 2014-04-26 18:05:14.228--ServerSession(320769650)--Thread(Thread[EJB default - 1,5,EJB default])--client acquired: 1096067977
[EL Finer]: transaction: 2014-04-26 18:05:14.236--ClientSession(1096067977)--Thread(Thread[EJB default - 1,5,EJB default])--acquire unit of work: 698749338
[EL Finest]: transaction: 2014-04-26 18:05:14.237--UnitOfWork(698749338)--Thread(Thread[EJB default - 1,5,EJB default])--persist() operation called on: jpa.test.model.Student@55cdaad2.
[EL Finest]: connection: 2014-04-26 18:05:14.238--ServerSession(320769650)--Connection(118375432)--Thread(Thread[EJB default - 1,5,EJB default])--Connection acquired from connection pool [default].
[EL Finest]: query: 2014-04-26 18:05:14.24--ClientSession(1096067977)--Thread(Thread[EJB default - 1,5,EJB default])--Execute query DataModifyQuery(name="TABLE_SEQ" sql="UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + #PREALLOC_SIZE WHERE SEQ_NAME = #SEQ_NAME")
[EL Finest]: connection: 2014-04-26 18:05:14.242--ClientSession(1096067977)--Thread(Thread[EJB default - 1,5,EJB default])--reconnecting to external connection pool
[EL Fine]: sql: 2014-04-26 18:05:14.249--ClientSession(1096067977)--Connection(1243300871)--Thread(Thread[EJB default - 1,5,EJB default])--UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?
    bind => [50, TABLE_SEQ]
[EL Finest]: query: 2014-04-26 18:05:14.252--ClientSession(1096067977)--Thread(Thread[EJB default - 1,5,EJB default])--Execute query ValueReadQuery(name="TABLE_SEQ" sql="SELECT SEQ_COUNT FROM SEQUENCE WHERE SEQ_NAME = #SEQ_NAME")
[EL Fine]: sql: 2014-04-26 18:05:14.253--ClientSession(1096067977)--Connection(1243300871)--Thread(Thread[EJB default - 1,5,EJB default])--SELECT SEQ_COUNT FROM SEQUENCE WHERE SEQ_NAME = ?
    bind => [TABLE_SEQ]
[EL Finest]: sequencing: 2014-04-26 18:05:14.256--ClientSession(1096067977)--Connection(1243300871)--Thread(Thread[EJB default - 1,5,EJB default])--local sequencing preallocation for TABLE_SEQ: objects: 50 , first: 1, last: 50
[EL Finest]: connection: 2014-04-26 18:05:14.258--ServerSession(320769650)--Connection(118375432)--Thread(Thread[EJB default - 1,5,EJB default])--Connection released to connection pool [default].
[EL Finest]: sequencing: 2014-04-26 18:05:14.259--UnitOfWork(698749338)--Thread(Thread[EJB default - 1,5,EJB default])--assign sequence to the object (1 -> jpa.test.model.Student@55cdaad2)
[org.hibernate.validator.util.Version] (EJB default - 1) Hibernate Validator 4.2.0.Final
[EL Finest]: transaction: 2014-04-26 18:05:14.325--UnitOfWork(698749338)--Thread(Thread[EJB default - 1,5,EJB default])--persist() operation called on: jpa.test.model.Student@59887d29.
[EL Finest]: connection: 2014-04-26 18:05:14.326--ServerSession(320769650)--Connection(265370795)--Thread(Thread[EJB default - 1,5,EJB default])--Connection acquired from connection pool [default].
[EL Finest]: query: 2014-04-26 18:05:14.327--ClientSession(1096067977)--Thread(Thread[EJB default - 1,5,EJB default])--Execute query DataModifyQuery(name="TABLE_SEQ" sql="UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?")
[EL Finest]: connection: 2014-04-26 18:05:14.328--ClientSession(1096067977)--Thread(Thread[EJB default - 1,5,EJB default])--reconnecting to external connection pool
[EL Fine]: sql: 2014-04-26 18:05:14.329--ClientSession(1096067977)--Connection(1910900393)--Thread(Thread[EJB default - 1,5,EJB default])--UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?
    bind => [50, TABLE_SEQ]
[EL Finest]: query: 2014-04-26 18:05:14.331--ClientSession(1096067977)--Thread(Thread[EJB default - 1,5,EJB default])--Execute query ValueReadQuery(name="TABLE_SEQ" sql="SELECT SEQ_COUNT FROM SEQUENCE WHERE SEQ_NAME = ?")
[EL Fine]: sql: 2014-04-26 18:05:14.332--ClientSession(1096067977)--Connection(1910900393)--Thread(Thread[EJB default - 1,5,EJB default])--SELECT SEQ_COUNT FROM SEQUENCE WHERE SEQ_NAME = ?
    bind => [TABLE_SEQ]
[EL Finest]: sequencing: 2014-04-26 18:05:14.334--ClientSession(1096067977)--Connection(1910900393)--Thread(Thread[EJB default - 1,5,EJB default])--local sequencing preallocation for TABLE_SEQ: objects: 50 , first: 51, last: 100
[EL Finest]: connection: 2014-04-26 18:05:14.335--ServerSession(320769650)--Connection(265370795)--Thread(Thread[EJB default - 1,5,EJB default])--Connection released to connection pool [default].
[EL Finest]: sequencing: 2014-04-26 18:05:14.336--UnitOfWork(698749338)--Thread(Thread[EJB default - 1,5,EJB default])--assign sequence to the object (51 -> jpa.test.model.Student@59887d29)
[EL Finest]: transaction: 2014-04-26 18:05:14.337--UnitOfWork(698749338)--Thread(Thread[EJB default - 1,5,EJB default])--persist() operation called on: jpa.test.model.Student@20f5e794.
[EL Finest]: connection: 2014-04-26 18:05:14.338--ServerSession(320769650)--Connection(1882633843)--Thread(Thread[EJB default - 1,5,EJB default])--Connection acquired from connection pool [default].
[EL Finest]: query: 2014-04-26 18:05:14.338--ClientSession(1096067977)--Thread(Thread[EJB default - 1,5,EJB default])--Execute query DataModifyQuery(name="TABLE_SEQ" sql="UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?")
[EL Finest]: connection: 2014-04-26 18:05:14.339--ClientSession(1096067977)--Thread(Thread[EJB default - 1,5,EJB default])--reconnecting to external connection pool
[EL Fine]: sql: 2014-04-26 18:05:14.34--ClientSession(1096067977)--Connection(402944403)--Thread(Thread[EJB default - 1,5,EJB default])--UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?
    bind => [50, TABLE_SEQ]
[EL Finest]: query: 2014-04-26 18:05:14.342--ClientSession(1096067977)--Thread(Thread[EJB default - 1,5,EJB default])--Execute query ValueReadQuery(name="TABLE_SEQ" sql="SELECT SEQ_COUNT FROM SEQUENCE WHERE SEQ_NAME = ?")
[EL Fine]: sql: 2014-04-26 18:05:14.343--ClientSession(1096067977)--Connection(402944403)--Thread(Thread[EJB default - 1,5,EJB default])--SELECT SEQ_COUNT FROM SEQUENCE WHERE SEQ_NAME = ?
    bind => [TABLE_SEQ]
[EL Finest]: sequencing: 2014-04-26 18:05:14.345--ClientSession(1096067977)--Connection(402944403)--Thread(Thread[EJB default - 1,5,EJB default])--local sequencing preallocation for TABLE_SEQ: objects: 50 , first: 101, last: 150
[EL Finest]: connection: 2014-04-26 18:05:14.346--ServerSession(320769650)--Connection(1882633843)--Thread(Thread[EJB default - 1,5,EJB default])--Connection released to connection pool [default].
[EL Finest]: sequencing: 2014-04-26 18:05:14.347--UnitOfWork(698749338)--Thread(Thread[EJB default - 1,5,EJB default])--assign sequence to the object (101 -> jpa.test.model.Student@20f5e794)
[EL Finer]: transaction: 2014-04-26 18:05:14.348--UnitOfWork(698749338)--Thread(Thread[EJB default - 1,5,EJB default])--begin unit of work flush
[EL Finest]: query: 2014-04-26 18:05:14.351--UnitOfWork(698749338)--Thread(Thread[EJB default - 1,5,EJB default])--Execute query InsertObjectQuery(jpa.test.model.Student@59887d29)
[EL Finest]: connection: 2014-04-26 18:05:14.353--ServerSession(320769650)--Connection(1582457600)--Thread(Thread[EJB default - 1,5,EJB default])--Connection acquired from connection pool [default].
[EL Finest]: connection: 2014-04-26 18:05:14.354--ClientSession(1096067977)--Thread(Thread[EJB default - 1,5,EJB default])--reconnecting to external connection pool
[EL Fine]: sql: 2014-04-26 18:05:14.354--ClientSession(1096067977)--Connection(1927398752)--Thread(Thread[EJB default - 1,5,EJB default])--INSERT INTO STUDENTS (ID_STUDENT, NAME) VALUES (?, ?)
bind => [51, Paolo]

[EL Finest]: query: 2014-04-26 18:05:14.37--UnitOfWork(698749338)--Thread(Thread[EJB default - 1,5,EJB default])--Execute query InsertObjectQuery(jpa.test.model.Student@55cdaad2)
[EL Fine]: sql: 2014-04-26 18:05:14.371--ClientSession(1096067977)--Connection(1927398752)--Thread(Thread[EJB default - 1,5,EJB default])--INSERT INTO STUDENTS (ID_STUDENT, NAME) VALUES (?, ?)
    bind => [1, Anna]
[EL Finest]: query: 2014-04-26 18:05:14.373--UnitOfWork(698749338)--Thread(Thread[EJB default - 1,5,EJB default])--Execute query InsertObjectQuery(jpa.test.model.Student@20f5e794)
[EL Fine]: sql: 2014-04-26 18:05:14.373--ClientSession(1096067977)--Connection(1927398752)--Thread(Thread[EJB default - 1,5,EJB default])--INSERT INTO STUDENTS (ID_STUDENT, NAME) VALUES (?, ?)
    bind => [101, Luigi]
[EL Finer]: transaction: 2014-04-26 18:05:14.375--UnitOfWork(698749338)--Thread(Thread[EJB default - 1,5,EJB default])--end unit of work flush
[EL Finer]: transaction: 2014-04-26 18:05:14.376--UnitOfWork(698749338)--Thread(Thread[EJB default - 1,5,EJB default])--resume unit of work
Exiting org.jboss.invocation.InterceptorContext$Invocation.insertStudent
Business method insertStudent in org.jboss.invocation.InterceptorContext$Invocation takes 5878 ms to execute
18:05:14,409 INFO  [org.jboss.as.naming] (Remoting "pc" task-1) JBAS011806: Channel end notification received, closing channel Channel ID 03cefe33 (inbound) of Remoting connection 3138554d to /127.0.0.1:65303

1 个答案:

答案 0 :(得分:0)

问题解决了。 为了能够很好地处理EclipseLink事务,必须指定(在persistence.xml文件中)我们使用的服务器,在我的情况下:

<property name="eclipselink.target-server" value="JBoss"/>