java - JPA 存储库 findById 被 $$_hibernate_interceptor 拦截

标签 java spring-boot spring-data-jpa

我有一个 Spring Boot 应用程序。我有不同的实体,它们都有类似的方法。 在启动应用程序之前,我运行 schema.sql 和 data.sql 文件来初始化 postgres 数据库。 当尝试使用repository.getById(id)获取实体(在我的例子中为文章)时,我得到一个Article$HibernateProxy$而不是普通的Article。无论出于何种原因,它都会被 ByteBuddyInterceptor 拦截。 同时,我对不同的实体(订单)使用相同的方法,并得到正常的预期订单。

当使用repository.findAll()获取所有文章时,我得到了一个正常的文章列表。

这种奇怪的行为有原因吗?我可以以某种方式禁用这个拦截器吗?

my results

这是我的文章类:

@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/

相关文章:

java - 如何从JPA中具有相同值的一列中获取sql中的唯一行?

java - org.hibernate.id.IdentifierGenerationException : "attempted to assign id from null one-to-one property"

java - 在 Java 中将月份字符串转换为整数

java - TextView 中从右到左的文本

java - 如果路径包含空格,则以 Zip 格式归档的 URI 不正确

java - Spring MVC Rest - URL 中的多个参数

hibernate - org.hibernate.tool.schema.spi.CommandAcceptanceException : Error executing DDL

java - 找到多于一行具有给定标识符的行

java - jackson 数据绑定(bind)

java - 在 Spring Boot 中使用 LDAP 进行身份验证时出错原因 : [LDAP: error code 50 - Insufficient Access Rights]