【问题标题】:Hibernate sequence generator always 0休眠序列生成器始终为 0
【发布时间】:2015-05-18 14:00:38
【问题描述】:

我正在尝试配置一个映射类以使用我在 postgres 数据库中定义的序列。当我尝试保留任何实体时,ID 始终为零,如果我使用 select nextval('item_seq'),我将得到 1(或下一个 val)。我使用 intellij 重新生成类。这个项目中的休眠版本是 3.6.0,如果这可能是我的问题的一部分?

@Entity
@Table(name = "item")
public class Item {
    private int itemid;
    ...

    @Basic
    @Id
    @SequenceGenerator(name = "item_seq", sequenceName = "item_seq", allocationSize = 1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "item_seq")
    @Column(name = "itemid", unique = true, nullable = false, insertable = true, updatable = true)

    public int getItemid() {
        return itemid;
    }
    ...
}

用法

Item item = new Item();
item.setCreated(new Date());
item.setVendorId(vendorId);
save(item); // essentially is getHibernateTemplate().save(Item.class.getName(), item);

-- 编辑--

我一直在尝试以下建议,但一切似乎都在继续生成 0 作为 id 或抛出异常“必须在调用 save() 之前手动分配此类的 id”。这就是我现在所处的位置,作为最后的努力,我尝试将注释移动到变量声明而不是 getter。没有帮助。

@Entity
@Table(name = "item")
public class Item {
    @Id
    //@SequenceGenerator(name = "item_seq", sequenceName = "item_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.IDENTITY) //, generator = "item_seq")
    @Column(name = "itemid", unique = true, nullable = false) //, insertable = true, updatable = true)
    private Long itemid;
...

    public Long getItemid() {
        return itemid;
    }
}

【问题讨论】:

  • 我在一个项目中使用了 postgres + hibernate 并且工作得很好。尝试删除allocationSize = 1。通常hibernate在插入之前会选择nextval('item_seq')。
  • 我尝试从序列生成器注释中删除 allocationSize 选项,但没有改变。还结合将类型更改为“整数”进行了尝试。
  • 将 IDENTITY 生成器策略与 postgres 一起使用,并且不定义序列。它有效

标签: java hibernate postgresql annotations sequence


【解决方案1】:

这对我总是有效(不过是 Hibernate 4.x):

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Id 使列成为主键(唯一,无空值),因此您不需要 @Column(...) 注释。有什么东西在某处设置您的itemId 吗?如果你有一个 setter,你可以删除它(Hibernate 不需要)。

【讨论】:

  • 我更改了 itemid 和持久性类的类型,我得到“必须在调用 save() 之前手动分配此类的 ID”。我会更新我的帖子。
  • 我升级到休眠 4,这就是我的工作设置的配置方式。应该早点接受这个...
【解决方案2】:

尝试为实体类中的给定表和序列提供数据库模式名称。 确保您的应用程序用户对序列具有特权(授予)。

-- 更新--

我认为解决方案是here

【讨论】:

  • 同一个用户是我所有表和序列的所有者。
  • 我的注释与该帖子中使用的解决方案相匹配,同样的例外。
【解决方案3】:

我遇到了同样的问题,这就是我为解决问题所做的工作

我使用 Hibernate 工具自动生成 POJO,并且所有注释都放置在方法级别,但是,Spring 建议(需要?)它们在字段级别。您也不能只将 Id 注释移动到字段级别,因为它要么是一个,要么是另一个(我尝试这个时遇到了一些其他异常)。所以我按照this 的回答来自定义Hibernate 工具,以在字段级别生成带有注释的POJO。

现在我的代码看起来像这样,它使用数据库序列序列就好了。

@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="my_seq")
@SequenceGenerator(name="my_seq",sequenceName="SPT_PROJECT_SEQ", allocationSize=1)
@Column(name = "PROJECT_ID", unique = true, nullable = false, precision = 10, scale = 0)
private long projectId;

希望对你有帮助

【讨论】:

    【解决方案4】:

    你正在使用什么数据库? 可能是不支持序列的数据库??

    尝试使用 strategy=auto 看看它是如何工作的

    由于 'select nextval(...)' 有效,您的数据库 (postgresql) 支持序列。所以不是这样的

    也许由于某种原因,hibernate 威胁你 int == 0 作为一个 id 并且它试图更新它而不是插入一个新记录( int =0 的默认值)只需将你的 id 类型更改为 Integer 并查看是否它解决了问题

    【讨论】:

    • 当我尝试将类型设置为“Integer”时,hibernate 抛出异常“必须在调用 save() 之前手动分配此类的 ID”。我什至尝试将生成策略更改为 IDENTITY,就像我在很多帖子中看到的那样,但抛出了相同的异常。
    • 好吧idis must be manually set 显然是标志,而不是忽略序列生成器。只是为了它,你可以在没有@Basic 的情况下运行它,看看它会怎么样?
    • 试过删除@Basic,没有区别。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    相关资源
    最近更新 更多