具有 PostgreSQL 初始序列池和更改的 JPA 2
JPA 2 with PostgreSQL initial sequence pooling and alteration
我有 Java SE 应用程序使用 Eclipselink 作为 Postgres 数据库的持久性提供程序,我在应用程序初始化时遇到了奇怪的行为。
事情是我的一个实体将 ID 设置为从 postgres 的序列中汇集。在应用程序初始化时,将日志记录级别设置为正常,我可以看到该 ID 被提取了两次,因此序列每次都递增 1。
日志:
[EL Info]: 2015-01-22 19:25:13.659--ServerSession(1107730949)--Thread(Thread[main,5,main])--EclipseLink, version: Eclipse Persistence Services - 2.5.0.v20130507-3faac2b
[EL Fine]: connection: 2015-01-22 19:25:13.751--Thread(Thread[main,5,main])--Detected database platform: org.eclipse.persistence.platform.database.PostgreSQLPlatform
[EL Config]: connection: 2015-01-22 19:25:13.766--ServerSession(1107730949)--Connection(1370979551)--Thread(Thread[main,5,main])--connecting(DatabaseLogin(
platform=>PostgreSQLPlatform
user name=> "intime"
datasource URL=> "jdbc:postgresql://localhost:5432/InTime?charSet=LATIN2"
))
[EL Config]: connection: 2015-01-22 19:25:13.77--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--Connected: jdbc:postgresql://localhost:5432/InTime?charSet=LATIN2
User: intime
Database: PostgreSQL Version: 9.3.5
Driver: PostgreSQL Native Driver Version: PostgreSQL 9.3 JDBC4.1 (build 1102)
[EL Info]: connection: 2015-01-22 19:25:13.901--ServerSession(1107730949)--Thread(Thread[main,5,main])--file:/home/tepo/IdeaProjects/WebParser/target/classes/_parser_writable login successful
[EL Fine]: sql: 2015-01-22 19:25:13.986--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--select nextval(timetable)
[EL Fine]: sql: 2015-01-22 19:25:13.99--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--ALTER SEQUENCE timetable INCREMENT BY 1
[EL Fine]: sql: 2015-01-22 19:25:13.992--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--select nextval(timetable)
[EL Fine]: sql: 2015-01-22 19:25:13.993--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--ALTER SEQUENCE timetable INCREMENT BY 1
[EL Fine]: sql: 2015-01-22 19:25:14.041--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--SELECT ID, CODE, DAYCAT FROM "public"."DAYCATCODEMAP"
[EL Fine]: sql: 2015-01-22 19:25:14.049--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--SELECT ID, CODE, READABLE FROM "public"."CT_EXCLUSION"
[EL Fine]: sql: 2015-01-22 19:25:14.05--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--SELECT ID, ABBREVIATION, FULLNAME FROM "public"."REGION"
这发生在应用初始化的最开始,甚至在 entityManagerFactory 初始化之前。
最后,当应用程序为 运行 时,这会导致插入带有移位 ID 的记录。
这是一个实体:
@Table(name = "\"TIMETABLE\"", catalog = "public")
@Entity
@NamedQuery(
name = "deleteTimetableByIds",
query = "DELETE FROM Timetable T where T.id = :id"
)
@SequenceGenerator(name="TTBL_SEQ", sequenceName="timetable", allocationSize = 1)
public class Timetable{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TTBL_SEQ")
private Long id;
...
}
persistence.xml:
<persistence-unit name="parser_writable" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.target-database" value="PostgreSQL" />
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.url"
value="jdbc:postgresql://localhost:5432/InTime?charSet=LATIN2"/>
<property name="javax.persistence.jdbc.user" value="intime"/>
<property name="javax.persistence.jdbc.password" value="intime"/>
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
<property name="eclipselink.ddl-generation.output-mode"
value="database"/>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
所以,当我初始化 PersistenceManager class 时会发生这种情况,这意味着此方法:
private static EntityManager em_write = null;
private static EntityManagerFactory factory;
public static void initializeEntityManager() {
if (em_write == null) {
factory = Persistence.createEntityManagerFactory("parser_writable");
em_write = factory.createEntityManager();
}
明显的问题是为什么会发生这种情况以及如何避免这种情况?
我认为问题是:您在 class 之上使用 @SequenceGenerator 尝试使用 @SequenceGenerator和 @GeneratedValue 注释仅适用于 pk/unique 列:
@Id
@SequenceGenerator(name="TTBL_SEQ", sequenceName="timetable", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TTBL_SEQ")
private Long id;
知道了!
<property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
造成了这个麻烦。也许我应该提出错误报告..
我有 Java SE 应用程序使用 Eclipselink 作为 Postgres 数据库的持久性提供程序,我在应用程序初始化时遇到了奇怪的行为。 事情是我的一个实体将 ID 设置为从 postgres 的序列中汇集。在应用程序初始化时,将日志记录级别设置为正常,我可以看到该 ID 被提取了两次,因此序列每次都递增 1。 日志:
[EL Info]: 2015-01-22 19:25:13.659--ServerSession(1107730949)--Thread(Thread[main,5,main])--EclipseLink, version: Eclipse Persistence Services - 2.5.0.v20130507-3faac2b
[EL Fine]: connection: 2015-01-22 19:25:13.751--Thread(Thread[main,5,main])--Detected database platform: org.eclipse.persistence.platform.database.PostgreSQLPlatform
[EL Config]: connection: 2015-01-22 19:25:13.766--ServerSession(1107730949)--Connection(1370979551)--Thread(Thread[main,5,main])--connecting(DatabaseLogin(
platform=>PostgreSQLPlatform
user name=> "intime"
datasource URL=> "jdbc:postgresql://localhost:5432/InTime?charSet=LATIN2"
))
[EL Config]: connection: 2015-01-22 19:25:13.77--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--Connected: jdbc:postgresql://localhost:5432/InTime?charSet=LATIN2
User: intime
Database: PostgreSQL Version: 9.3.5
Driver: PostgreSQL Native Driver Version: PostgreSQL 9.3 JDBC4.1 (build 1102)
[EL Info]: connection: 2015-01-22 19:25:13.901--ServerSession(1107730949)--Thread(Thread[main,5,main])--file:/home/tepo/IdeaProjects/WebParser/target/classes/_parser_writable login successful
[EL Fine]: sql: 2015-01-22 19:25:13.986--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--select nextval(timetable)
[EL Fine]: sql: 2015-01-22 19:25:13.99--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--ALTER SEQUENCE timetable INCREMENT BY 1
[EL Fine]: sql: 2015-01-22 19:25:13.992--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--select nextval(timetable)
[EL Fine]: sql: 2015-01-22 19:25:13.993--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--ALTER SEQUENCE timetable INCREMENT BY 1
[EL Fine]: sql: 2015-01-22 19:25:14.041--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--SELECT ID, CODE, DAYCAT FROM "public"."DAYCATCODEMAP"
[EL Fine]: sql: 2015-01-22 19:25:14.049--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--SELECT ID, CODE, READABLE FROM "public"."CT_EXCLUSION"
[EL Fine]: sql: 2015-01-22 19:25:14.05--ServerSession(1107730949)--Connection(1142931081)--Thread(Thread[main,5,main])--SELECT ID, ABBREVIATION, FULLNAME FROM "public"."REGION"
这发生在应用初始化的最开始,甚至在 entityManagerFactory 初始化之前。
最后,当应用程序为 运行 时,这会导致插入带有移位 ID 的记录。 这是一个实体:
@Table(name = "\"TIMETABLE\"", catalog = "public")
@Entity
@NamedQuery(
name = "deleteTimetableByIds",
query = "DELETE FROM Timetable T where T.id = :id"
)
@SequenceGenerator(name="TTBL_SEQ", sequenceName="timetable", allocationSize = 1)
public class Timetable{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TTBL_SEQ")
private Long id;
...
}
persistence.xml:
<persistence-unit name="parser_writable" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.target-database" value="PostgreSQL" />
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.url"
value="jdbc:postgresql://localhost:5432/InTime?charSet=LATIN2"/>
<property name="javax.persistence.jdbc.user" value="intime"/>
<property name="javax.persistence.jdbc.password" value="intime"/>
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
<property name="eclipselink.ddl-generation.output-mode"
value="database"/>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
所以,当我初始化 PersistenceManager class 时会发生这种情况,这意味着此方法:
private static EntityManager em_write = null;
private static EntityManagerFactory factory;
public static void initializeEntityManager() {
if (em_write == null) {
factory = Persistence.createEntityManagerFactory("parser_writable");
em_write = factory.createEntityManager();
}
明显的问题是为什么会发生这种情况以及如何避免这种情况?
我认为问题是:您在 class 之上使用 @SequenceGenerator 尝试使用 @SequenceGenerator和 @GeneratedValue 注释仅适用于 pk/unique 列:
@Id
@SequenceGenerator(name="TTBL_SEQ", sequenceName="timetable", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TTBL_SEQ")
private Long id;
知道了!
<property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
造成了这个麻烦。也许我应该提出错误报告..