对于我的桌面应用程序,我使用JavaFX,Spring,JPA + Hibernate和PostgreSQL。目前我遇到了几个问题。
问题:违反PRIMARY KEY约束SQL错误
当我按照以下方式创建实体类(GenerationType为AUTO)时,它工作正常。但是当我创建一个新的数据库并使用sql脚本添加一些测试数据时(如下图所示)并尝试使用我的应用程序插入一些数据,我得到了“违反PRIMARY KEY约束”的SQL错误。这意味着似乎Hibernate尝试生成已经可用的PK值(使用我的测试数据ex 1,2,3等分配)。但是经过5次尝试(超过测试数据最大pk值)就可以了,用6个PK键值开始插入数据。
实体类 - GenerationType为AUTO
@Entity
@Table(name = "devicetype")
public class Devicetype implements Serializable {
@Id
@Basic(optional = false)
@Column(name = "id")
private Integer id;
}
包含初始测试数据的表
EntityManager工厂
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
<property name="packagesToScan" value="com.core.domain" />
<property name="jpaProperties">
<props>
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgresPlusDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.use_sql_comments">false</prop>
<prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
</props>
</property>
</bean>
问题二:差距在序列值
中为了解决错误,我按照以下方式更改了Entity类(使用GenerationType作为SEQUENCE)并完成相同的步骤(使用sql脚本插入初始测试数据并尝试通过应用程序插入数据)。然后插入数据,没有任何异常。现在我的表包含通过脚本和应用程序插入的记录(如下图所示)。但是通过应用程序新添加数据(我在浅蓝色上突出显示)具有非常高的PK值(从184开始而不是从6开始)。这意味着“GenerationType as SEQUENCE”似乎hibernate没有按顺序方式填充ID值(保持一些空白)。当我通过应用程序进一步添加一些数据时,似乎将使用另一个更高的ID值插入数据(不是启动表单214)。这意味着ID似乎没有按顺序递增。
实体类 - GenerationType为SEQUENCE
@Entity
@Table(name = "device_type")
public class DeviceType implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name="my_seq", sequenceName="MY_SEQ", allocationSize=1, initialValue=1)
@Basic(optional = false)
@Column(name = "ID")
private Integer id;
}
带有间隙的表数据(序列ID)
答案 0 :(得分:2)
这就是序列(以及PostgreSQL SERIAL类型)的行为方式。
如果您手动插入值,则需要update the sequence accordingly。或者,更常见的是,不要手动插入值并让序列执行此操作。
除非你想在每个插件上锁定表并消除任何并发希望,否则差距是不可避免的。我建议不要关心。记住 - 这些数字并不意味着什么,它们只是一个方便的标识符。
花几分钟阅读这一切是如何运作的:CREATE SEQUENCE,ALTER SEQUENCE