Reputation: 53
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?
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.
Upvotes: 2
Views: 1543
Reputation: 1420
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.
Upvotes: 2