我有一个 Spring Boot 应用程序。我有不同的实体,它们都有类似的方法。 在启动应用程序之前,我运行 schema.sql 和 data.sql 文件来初始化 postgres 数据库。 当尝试使用repository.getById(id)获取实体(在我的例子中为文章)时,我得到一个Article$HibernateProxy$而不是普通的Article。无论出于何种原因,它都会被 ByteBuddyInterceptor 拦截。 同时,我对不同的实体(订单)使用相同的方法,并得到正常的预期订单。
当使用repository.findAll()
获取所有文章时,我得到了一个正常的文章列表。
这种奇怪的行为有原因吗?我可以以某种方式禁用这个拦截器吗?
这是我的文章类:
@Entity
@Table(name="article")
public class Article{
/// ID
@Id
@SequenceGenerator(name = "article_id_seq", sequenceName = "article_id_seq", allocationSize = 1)
@GeneratedValue(generator = "article_id_seq")
private Long id;
/// Attributes
private String name;
private String description;
private String imageUrl;
Float price;
Float palletSpace;
Float maxStack;
/// Constructor
public Article(String name, String description, String imageUrl, Float price, Float palletSpace, Float maxStack) {
this.name = name;
this.description = description;
this.imageUrl = imageUrl;
this.price = price;
this.palletSpace = palletSpace;
this.maxStack = maxStack;
}
public Article(){}
/// Methods
/// Special Getters & Setters
public float getPalletProductRatio(){
return (palletSpace / maxStack);
}
/// Getter & Setter
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public float getPalletSpace() {
return palletSpace;
}
public void setPalletSpace(float palletSpace) {
this.palletSpace = palletSpace;
}
public float getMaxStack() {
return maxStack;
}
public void setMaxStack(float maxStack) {
this.maxStack = maxStack;
}
public String getUrl() {
return imageUrl;
}
public void setUrl(String url) {
this.imageUrl = url;
}
}
这是我的订单类:
@Entity
@Table(name="shipster_order")
public class Order {
/// ID
@Id
@SequenceGenerator(name = "order_id_seq", sequenceName = "order_id_seq", allocationSize = 1)
@GeneratedValue(generator = "order_id_seq")
private Long id;
/// Attributes
private Long userId;
private String orderStatus;
private Date lastUpdateDate;
private Date basketDate;
private Date orderDate;
private Date shippingDate;
private Date deliveryDate;
private Date cancellationDate;
/// Constructor
public Order(User user){
this.userId = user.getUserId();
this.orderStatus = OrderStatus.BASKET.name();
this.lastUpdateDate = new Date();
this.basketDate = new Date();
this.orderDate = new Date(0);
this.shippingDate = new Date(0);
this.deliveryDate = new Date(0);
this.cancellationDate = new Date(0);
}
public Order(long userId){
this.userId = userId;
this.orderStatus = OrderStatus.BASKET.name();
this.lastUpdateDate = new Date();
this.basketDate = new Date();
this.orderDate = new Date(0);
this.shippingDate = new Date(0);
this.deliveryDate = new Date(0);
this.cancellationDate = new Date(0);
}
public Order(){}
public OrderStatus getOrderStatus() /*throws IllegalArgumentException*/{
return OrderStatus.valueOf(orderStatus);
}
public void setOrderStatus(OrderStatus inOrderStatus) {
this.orderStatus = inOrderStatus.name();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public long getUserId() {
return userId;
}
public void setUserId(long userId) {
this.userId = userId;
}
public Date getLastUpdateDate() {
return lastUpdateDate;
}
public void setLastUpdateDate(Date lastUpdateDate) {
this.lastUpdateDate = lastUpdateDate;
}
public Date getBasketDate() {
return basketDate;
}
public void setBasketDate(Date basketDate) {
this.basketDate = basketDate;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
public Date getShippingDate() {
return shippingDate;
}
public void setShippingDate(Date shippingDate) {
this.shippingDate = shippingDate;
}
public Date getDeliveryDate() {
return deliveryDate;
}
public void setDeliveryDate(Date deliveryDate) {
this.deliveryDate = deliveryDate;
}
public Date getCancellationDate() {
return cancellationDate;
}
public void setCancellationDate(Date cancellationDate) {
this.cancellationDate = cancellationDate;
}
}
对于这两个类,我使用内置的 JPA findById
方法。
这是我调用两个 findById()
方法的方法:
public void add(Long articleId, Long orderId, int inQuantity) throws Exception {
Article article = articleRepository.getById(articleId);
Order order = orderRepository.getById(orderId);
add(article, order, inQuantity);
}
非常感谢您的帮助。
最佳答案
首先您应该知道,从 Spring Data JPA 2.7.0
开始,JpaRepository#getById(ID)
方法已被删除。详情可查看here .
JpaRepository#getById(ID)
方法仅返回实体的引用代理。
/*
* (non-Javadoc)
* @see org.springframework.data.jpa.repository.JpaRepository#getById(java.io.Serializable)
*/
@Override
public T getById(ID id) {
Assert.notNull(id, ID_MUST_NOT_BE_NULL);
return em.getReference(getDomainClass(), id);
}
JpaRepository#findById(ID)
方法返回您的真实数据库实体,而不是引用代理。
/*
* (non-Javadoc)
* @see org.springframework.data.repository.CrudRepository#findById(java.io.Serializable)
*/
@Override
public Optional<T> findById(ID id) {
Assert.notNull(id, ID_MUST_NOT_BE_NULL);
Class<T> domainType = getDomainClass();
if (metadata == null) {
return Optional.ofNullable(em.find(domainType, id));
}
LockModeType type = metadata.getLockModeType();
Map<String, Object> hints = new HashMap<>();
getQueryHints().withFetchGraphs(em).forEach(hints::put);
return Optional.ofNullable(type == null ? em.find(domainType, id, hints) : em.find(domainType, id, type, hints));
}
请尝试使用 findById(ID)
而不是 getById(ID)
。
有关这两种方法的更多详细信息,您可以查看问题与解答here .
关于java - JPA 存储库 findById 被 $$_hibernate_interceptor 拦截,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72302690/