如何解决休眠:@Columnupdatable = false不适用于@MappedSuperclass
我正在将Spring Data JPA与Hibernate一起使用,并且在@Column批注上使用updatable = false属性时遇到了麻烦。
我的所有@Entity对象都有一个基类,其createdDate定义如下:
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@Setter
@Getter
@ToString
public abstract class BaseEntity {
@CreatedBy
@Column(name = "CREATE_USER_ID",nullable = false,updatable = false)
protected String createdBy;
@CreationTimestamp
@Column(name = "CREATE_TS",columnDeFinition = "TIMESTAMP WITH TIME ZONE",updatable = false)
protected Instant createdDate; //Audit for data use replication conflict resolution (Oracle Golden Gate)
@LastModifiedBy
@Column(name = "LAST_UPDATE_USER_ID")
protected String lastModifiedBy;
@UpdateTimestamp
@Column(name = "LAST_UPDATE_TS",columnDeFinition = "TIMESTAMP WITH TIME ZONE")
protected Instant lastModifiedDate;
以下是我的子实体
@Entity
@Table(name = "CUSTOMER")
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString(exclude = {""})
public class Customer extends BaseEntity
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "CUSTOMER_ID_SEQ")
@SequenceGenerator(sequenceName = "Customer_ID_SEQ",allocationSize = 1,name = "CUSTOMER_ID_SEQ")
@Column(name = "CUSTOMER_ID")
private Long CustomerId; //Primary identifier
@Column(name = "CUSTOMER_NAME")
private String customerName; //Customer Name
@Column(name = "COUNTRY")
private String customerCountry; //Customer Country
@Column(name = "REGION")
private String customerRegion; //Customer Region
}
CustomerService.java中的代码段
public CustomerDetails updateCustomer(CustomerDetails customerDetails,Long customerId) {
Customer customer = customerEntityToDTOMapper.dtoToEntity(customerDetails);
/**
Some sort of business logic
**/
Customer updatedCustomer = customerRepository.saveAndFlush(customer);
return customerEntityToDTOMapper.entityToDTO(updatedCustomer);
}
现在,当我从邮递员调用updateCustomer API时,如果我更改了请求正文中的createdDate的值,它将在数据库中进行更新(数据库将用在请求正文中传递的新值替换createdDate的实际值)。理想情况下,这应该不会发生。无论我在requestBody中传递什么有效值,都不应在updateCustomer API调用中使用数据库中的createdDate。
同样在createCustomer请求中,如果createdDate = null,JPA将根据期望设置createdDate,并且我在repository.saveAndFlush()方法的响应中收到正确的日期。但是在updateCustomer中,如果我在实体中设置了createdDate = null,那么createdDate在repository.saveAndFlush()方法的响应中为null,即使它存在于数据库中。
有人可以帮助我解决我的问题吗?
解决方法
处理@Column
批注属性以创建/更新/验证架构等,并从实体定义表上的约束(取决于hbm2ddl.auto属性)。
现在insertable
使用updatable
和@persistenceContext
发出查询,如果未显式提供查询并将其设置为false,它将忽略其查询中的字段。
由于您的情况尚未提供代码,而是如何设置值,因此我假设在update
的情况下,您将createdDate
设置为null,因为您将其设置为无效已将字段定义为
@CreationTimestamp // This will add the timestamp if null when entity is new only
@Column(name = "CREATE_TS",columnDefinition = "TIMESTAMP WITH TIME ZONE",nullable = false,updatable = false)
protected Instant createdDate;
因此,您的更新将createdDate
显式更新为null,这将覆盖updatable=false
和AFAIK,而updatable=false
有一些奇怪的行为,它在实体中返回null(当您提取时保存后),然后再次保存实体时,会保留null值(无论updatable = false都会保存该值,因为hibernate会看到该值更改为null)
我建议删除updatable=false
并仅使用@CreationTimeStamp
属性,这将不会更新值See this,并且数据库约束应该存在以防止null
>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。