【发布时间】:2019-05-14 22:53:09
【问题描述】:
对于我的一个实体,我想使用 UUID 作为主键而不是 Long。实体扩展了 AbstractEntityUUID:
@MappedSuperclass
public abstract class AbstractEntityUUID implements Serializable {
private static final long serialVersionUID = 40076842287035126L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
public UUID getId() {
return id;
}
@Override
public int hashCode() {
if (getId() != null) {
return getId().hashCode();
}
return super.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
AbstractEntityUUID other = (AbstractEntityUUID) obj;
if (getId() == null || other.getId() == null) {
return false;
}
if (!getId().equals(other.getId())) {
return false;
}
return true;
}
}
实体本身是:
@Entity
@Table(schema = "schemaName", name = "order")
@DynamicUpdate
public class Order extends AbstractEntityUUID {
private static final long serialVersionUID = 6358231835578038565L;
@Column(precision = 10, scale = 2)
protected BigDecimal itemPrice;
@Temporal(TIMESTAMP)
@Basic(fetch = LAZY)
protected Date purchaseDate;
// other properties and getters & setters ...
}
persist 方法工作正常:
Order order = new Order();
order.setItemPrice(BigDecimal.ONE);
order = getEM().persist(order);
使用正确信息在数据库表上创建一个新行。以后有合并的时候就是问题发生的时候:
order.setPurchaseDate(new Date());
order = getEM().merge(order);
上一行似乎保持不变,并使用包含价格和日期的新主键创建了一个新行。
当主键为 Long 且 GenerationType.IDENTITY 时,行将正确更新,并且按预期工作。
这是在 WildFly 16 服务器上的 ejb 3 bean 上运行的。 Hibernate 的实现似乎是 5.3.9。数据库是 MySQL 服务器 5.7。
如果 Java 生成 UUID 值很好,我宁愿不更改它,除非需要使实体使用 UUID 作为主键。
【问题讨论】:
-
在这种情况下,如果实体在 .persist 或 .find 之后处于持久状态,则无需调用合并。当事务准备好提交时,Hibernate 将刷新更改。但我不确定为什么它在您的代码中没有按预期工作。
-
@arseniyadru 这是正确的。但是在同一个用例中,当实体具有 Long as PK 时,它会按预期工作。这只发生在 PK 是按照描述实现的 UUID 时。
-
id 实际生成的时间不清楚。您是否在代码中生成 UUID(未显示)?如果您依靠休眠来生成 UUID,我希望注释更像
@GeneratedValue(generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid") -
@Cascader 我已经有了注释 javax.persistence.GeneratedValue ,似乎我无法为其添加额外的属性 generator = "uuid"。 GenericGenerator 是特定于 Hibernate 的,我目前仅尝试使用 JPA 进行这项工作。
标签: java hibernate ejb jpa-2.0