【问题标题】:Hibernate not using defined sequence (postgresql)休眠不使用定义的序列(postgresql)
【发布时间】:2017-05-30 16:00:13
【问题描述】:

我正在尝试将映射对象插入具有正确 ID 的 postgresql 数据库。这就是我插入的方式:

Session session = Main.getSession();
Transaction rx = session.beginTransaction();
ProductsEntity productsEntity = new ProductsEntity();
productsEntity.setName(nameTextField.getText());
productsEntity.setDescription(descriptionTextArea.getText());
productsEntity.setCategory((ProductCategoriesEntity) categoryComboBox.getSelectedItem());
productsEntity.setPrice(new BigDecimal(1.0));
session.save(productsEntity);
tx.commit();
session.close();

具有定义顺序的类:

@Entity
@Table(name = "products", schema = "public", catalog = "shop")
public class ProductsEntity {
    private int id;
    private String name;
    private String description;
    private BigDecimal price;

    @Id
    @Column(name = "id", nullable = false)
    @SequenceGenerator(name="pk_sequence",sequenceName="products_id_seq")
    @GeneratedValue(strategy=GenerationType.AUTO,generator="pk_sequence")
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Basic
    @Column(name = "name", nullable = false, length = -1)
    public String getName() {
        return name;
    }

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

    @Basic
    @Column(name = "description", nullable = false, length = -1)
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Basic
    @Column(name = "price", nullable = false, precision = 2)
    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        ProductsEntity that = (ProductsEntity) o;

        if (id != that.id) return false;
        if (name != null ? !name.equals(that.name) : that.name != null) return false;
        if (description != null ? !description.equals(that.description) : that.description != null) return false;
        if (price != null ? !price.equals(that.price) : that.price != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + (description != null ? description.hashCode() : 0);
        result = 31 * result + (price != null ? price.hashCode() : 0);
        return result;
    }

    private ProductCategoriesEntity category;

    @ManyToOne
    public ProductCategoriesEntity getCategory() {
        return category;
    }

    public void setCategory(ProductCategoriesEntity category) {
        this.category = category;
    }
}

postgresql 序列 products_id_seq 的最后一个值为 4。Hibernate 正在插入 id=0 的对象,所以第一次插入成功,现在我遇到了唯一约束违规。

编辑 我通过添加生成器使序列工作

<generator class="identity"/>

在xml映射定义中

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="entities.ProductsEntity" table="products" schema="public" catalog="shop">
        <id name="id">
            <column name="id" sql-type="integer"/>
            <generator class="identity"/>
        </id>
        <property name="name">
            <column name="name" sql-type="varchar"/>
        </property>
        <property name="description">
            <column name="description" sql-type="varchar"/>
        </property>
        <property name="price">
            <column name="price" sql-type="numeric(9,2)" precision="9" scale="2"/>
        </property>
        <many-to-one name="category" column="category_id" class="entities.ProductCategoriesEntity" lazy="false"/>
    </class>
</hibernate-mapping>

这无需在类中定义顺序即可工作。我也尝试过使用

@GeneratedValue(strategy=GenerationType.IDENTITY)

在类文件中,但它不起作用。

如果有人有想法,请告诉我为什么只有“xml”方法有效。

【问题讨论】:

  • 您是使用 Hibernate 生成表还是通过控制台手动生成表?这确实对SequenceGenerator 注释产生了影响。
  • @coladict 带有序列的表是手动创建的,带有 xml 的类是由 inteliij ide 生成的
  • 使用@SequenceGenerator 时,allocationSize 必须与序列的增量值匹配。默认allocationSize 为50,默认增量大小为1,因此它会尝试插入重复ID。但是,如果该列从序列中获取它的默认值,则 @GeneratedValue(strategy=GenerationType.IDENTITY) 没有理由不工作。

标签: java postgresql hibernate


【解决方案1】:

序列“products_id_seq”是数据库序列吗?

如果是,则将您的 GenerationTypeAuto 更改为 SEQUENCE
我有一个与 Postgres 类似的设置,并将 GenerationType 设置为 SEQUENCE 并给 allocationSize = 1 为我工作。

此外,请确保您的序列与表格保持一致。如果没有,请暂时更改顺序,这样您的进一步更新就不会失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-30
    • 2014-12-09
    • 2017-08-13
    • 2018-01-26
    • 1970-01-01
    • 1970-01-01
    • 2016-01-03
    • 2014-11-28
    相关资源
    最近更新 更多