简体   繁体   中英

JPA Repository findById intercepted by $$_hibernate_interceptor

I have a Spring Boot application. I have different entities, which all have similar methods. Before starting the application, I run a schema.sql and data.sql file to initialize the postgres database. When trying to fetch an entity (in my case article) with repository.getById(id), I get an Article$HibernateProxy$ instead of a normal Article. for whatever reason, it is intercepted by a ByteBuddyInterceptor. At the same time, I use the same method for a different entity (order) and there I get a normal expected order back.

When fetching all articles with repository.findAll() , I get a normal list of articles back.

Is there a reason for this strange behavior? Can I somehow disable this interceptor?

my results

Here is my article class:

@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;
}

}

And here is my order class:

@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;
}

}

For both classes I use the built in JPA findById methods.

And here is the method where I call the two findById() methods:

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);
}

Thank you very much for your help.

First you should know the JpaRepository#getById(ID) method has been removed as of Spring Data JPA 2.7.0 . You can find the details here .

The JpaRepository#getById(ID) method only returns a reference proxy for the entity.

/*
 * (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);
}

The JpaRepository#findById(ID) method returns your real DB entity not a reference proxy.

/*
 * (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));
}

Please try using findById(ID) instead of getById(ID) .

For more detailed information about the two methods, you can review the questions and answers here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM