【问题标题】:Use of SERIAL and BIGSERIAL w/ EJB3 and Postgres使用带有 EJB3 和 Postgres 的 SERIAL 和 BIGSERIAL
【发布时间】:2012-07-03 14:04:33
【问题描述】:

如何在 ejb3 和 PostgreSQL 中使用 Serial 和 bigSerial?

【问题讨论】:

  • 您的问题严重缺乏细节。你有什么问题?

标签: java ejb ejb-3.0 postgresql-9.1


【解决方案1】:

假设当您说 EJB3 时,您打算使用 Java Persistence API (JPA),它是 Java EE 5 中 EJB3 规范的一部分,并在 Java EE 6 中被分离到 JPA 2:

使用IntegerLong、通常的@Column 注释和带有@SequenceGenerator@GeneratedValue 注释映射它。

假设您的 serialbigserial 列是标识列,并且您使用的是 Java EE 6 中的 JPA 2,您可以编写如下内容:

@Entity
@Table(name = "thetable")
public class TheTable implements Serializable {

    @Id
    @SequenceGenerator(name="tablename_id_seq", sequenceName="tablename_id_seq", allocationSize=1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="tablename_id_seq")
    @Basic(optional = false)
    @NotNull
    @Column(name = "id", updatable=false)
    private Integer id;

    // other columns...

    // then accessors ("getters and setters")

}

如果是BigSerial,使用Long而不是Integer,否则不需要更改。

我没有检查以上内容在 Java EE 5 中是否有效,原始 JPA 包含在 EJB3 中。如果您需要在 Java EE 5 上支持 JPA1,您可能需要进行更多检查。如果您必须支持 Java EE 5,我建议您从 JSR 220 spec for JPA 开始,但方式最好只迁移到 JPA2 和 Java EE 6 容器。

请注意,应该可以简单地使用GenerationType.IDENTITY 并避免为每个实体手动定义序列。不幸的是,至少对于 Hibernate,它假定您想对 所有 表使用全局“休眠”序列,这很愚蠢。

allocationSize=1 很重要。令人沮丧的是,JPA 指定最小 fetch 大小为 50,并期望在调用 nextval() 时序列以 50 的跳跃递增。除非你的序列是这样定义的,否则你会得到重复的键错误。

您将需要一个 META-INF/persistence.xml 文件来启用 JPA。对实体的访问是通过您从EntityMangerFactory 获得的EntityManager,或者更常见的是使用@PersistenceContext 注入它。请参阅 JPA 文档和关于“网络”的无尽教程。

JPA 实现随大多数应用程序服务器一起提供。 Glassfish 3 附带 EclipesLink 和 JBoss AS 7 附带 Hibernate 4。请参阅您的应用服务器的文档和 JPA 规范。

【讨论】:

  • FWIW,JPA 规范在组织上是 EJB 规范的一部分。 downloads for JSR-220, the EJB3 spec 包括“简化”(EJB3)、“ejbcore”(我认为是旧版 EJB)和“持久性”(JPA)的部分。不过,我同意将 JPA 视为 EJB 的一部分是错误的。
  • 好点@TomAnderson - 最初的 JPA 规范是 EJB3 的一部分,实际上是 Java EE 5 的一部分,而不是我想的 EE 6 的一部分。然而,规范存在分歧,在 Java EE 6 中,EJB3.1 (JSR 318) 与 JPA 2 (JSR 318) 是分开的。我一直在使用 EE6,忘记了 EJB3 中 JPA 的根源。谢谢指正。
  • @TomAnderson 已修复/澄清。这让我想知道 OP 是否真的想要 EJB3 完全,即来自 Java EE 5 的 JPA1,而不是 JPA2。如果是这样,他们应该这么说的。
  • 好点,他们现在已经非常明智地分开了。我应该记得的。对于 OP 真正想要的东西,你的猜测和我的猜测一样好!
【解决方案2】:

GenerationType.IDENTITY 适用于连续剧

CREATE TABLE vmb_mails (ID SERIAL PRIMARY KEY ,TITLE TEXT ........

@Entity
@Table(name="vmb_mails")
@NamedQueries(
    @NamedQuery(name="getAllMails",query="SELECT  m from Mail m ORDER by m.entDate DESC ")
)
//@SequenceGenerator(name="Mails_Seq_Gen",sequenceName="vmb_mails_seq",allocationSize=1)
public class Mail implements Serializable
{
    private long id;
    private String title;
    private String fromAddr;

    public Mail()
    {

    }
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="ID")
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }

...........

【讨论】:

  • 您正在使用哪个 JPA 实现来与它一起使用?我在使用 Hibernate 时遇到了很大的问题,不得不改用明确定义的序列。
  • 我正在使用 EJB3.1 ,在创建表时,会自动创建序列并与表关联。所以不需要显式地创建序列。我正在使用 glassfish 3.1。谢谢
  • Glassfish 3.1 表示 JPA2 和 EclipseLink。序列问题发生在 Hibernate 和直接从 SQL 定义的数据库中。你应该没事。顺便说一下,尝试区分 Java EE 6(整体规范)、EJB 3 和 JPA; EJB 和 JPA 规范已经分开,当你的意思是“JPA”时谈论“EJB”是非常混乱的。
猜你喜欢
  • 2016-07-14
  • 2019-11-16
  • 2019-03-10
  • 2017-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-30
  • 2015-01-17
相关资源
最近更新 更多