5 postgresql ejb jpa sequence glassfish-4
由于序列问题,我无法保留任何实体。我使用 Glssfish 4、Postgres 9.3 + JPA + EJB3 和 Netbeans 8。在例外情况下:
Finest: persist() operation called on: MyUser{id=null, email=a@e.it, password=test, firstname=test, lastname=test, company=Test}.
Finest: Execute query ValueReadQuery(sql="select nextval('mom_seq_id')")
Finest: Connection acquired from connection pool [read].
Finest: reconnecting to external connection pool
Fine: select nextval(mom_seq_id)
Finest: Connection released to connection pool [read].
Warning: Local Exception Stack:
Exception [EclipseLink-7027] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The sequence named [mom_seq_id] is setup incorrectly. Its increment does not match its pre-allocation size.
at org.eclipse.persistence.exceptions.ValidationException.sequenceSetupIncorrectly(ValidationException.java:1604)
at org.eclipse.persistence.sequencing.StandardSequence.createVector(StandardSequence.java:96)
...
Run Code Online (Sandbox Code Playgroud)
Postgres 上的序列:
CREATE SEQUENCE my_seq_id
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 27
CACHE 1;
ALTER TABLE my_seq_id
OWNER TO postgres;
COMMENT ON SEQUENCE my_seq_id
IS 'Sequence for autoincrement id on MyClass';
Run Code Online (Sandbox Code Playgroud)
以及我的实体的摘录:
@Entity
@Table(name = "myuser")
@XmlRootElement
public class MyUser implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name="MYSEQ",
sequenceName="my_seq_id")
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator="MYSEQ")
@Basic(optional = false)
@Column(name = "id")
private Integer id;
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释什么是错的?谢谢
我解决了我的问题,但我不知道为什么!我看到allocationSize()的默认值是50:
package javax.persistence;
@Target(value = {ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface SequenceGenerator {
public String name();
public String sequenceName() default "";
public String catalog() default "";
public String schema() default "";
public int initialValue() default 1;
public int allocationSize() default 50;
}
Run Code Online (Sandbox Code Playgroud)
我已经将我的 Postgres 序列increment_by值从 1更新到 50,现在它可以工作了!
由于我无法理解的原因,JPA 规范选择50作为序列生成器的默认增量。
PostgreSQL 默认为1.
如果两者不匹配,事情就会变得很糟糕,因为 JPA 认为它可以使用其他人也认为他们已经分配的值。至少 EclipseLink 检测到了这一点;Hibernate 只是继续愉快地尝试重新使用已分配的键。
如果您的顺序是:
CREATE SEQUENCE my_seq_id
INCREMENT 1
Run Code Online (Sandbox Code Playgroud)
那么您的映射必须反映:
@SequenceGenerator(name="MYSEQ",
sequenceName="my_seq_id", allocationSize=1)
Run Code Online (Sandbox Code Playgroud)
我强烈建议明确说明增量,即使您将其保留为默认值50并更改 PostgreSQL 序列。它会在以后调试时保存您和其他人的理智。
小智 4
将我的 Postgres 序列中的 INCREMENT 值从 1 更改为 50 解决了该问题。正如@unwichtich所建议的,最好通过@SequenceGenerator注释指定allocationSize=50属性。