【问题标题】:Lazily loaded entities in `Object` methods: `toString`, `equals` and `hashCode``Object` 方法中延迟加载的实体:`toString`、`equals` 和 `hashCode`
【发布时间】:2019-06-24 03:50:39
【问题描述】:

我为设备创建了一些模型,但我不确定我是否做了正确的映射,当我想摆脱急切加载时,我得到了错误:

"Type definition error: [simple type, class
org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor]; nested
exception is
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No
serializer found for class
org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no
properties discovered to create BeanSerializer (to avoid exception,
disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference
chain:
java.util.ArrayList[0]-com.winterrent.winterrent.entity.ItemProperty[\"item\"]-com.winterrent.winterrent.entity.Item$HibernateProxy$RO0mkQSh[\"hibernateLazyInitializer\"])",

但如果我将 fetch 类型更改为渴望一切正常。

我的逆向工程架构:

然后是我的实体:

import javax.persistence.*;
import java.util.Objects;

@Entity
@Table(name = "item")
public class Item {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Enumerated(EnumType.STRING)
    @Column(name = "type")
    private ItemType itemType;

    public Item() {

    }

    public Item(ItemType itemType) {
        this.itemType = itemType;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public ItemType getItemType() {
        return itemType;
    }

    public void setItemType(ItemType itemType) {
        this.itemType = itemType;
    }

    @Override
    public String toString() {
        return "Item{" +
                "id=" + id +
                ", itemType=" + itemType +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Item item = (Item) o;
        return id == item.id &&
                Objects.equals(itemType, item.itemType);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, itemType);
    }
}

2)

public enum ItemType {
    SKI, BOARD
}

3)

import javax.persistence.*;
import java.util.Objects;

@Entity
@Table(name = "item_property_definition")
public class ItemPropertyDefinition {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "property_name")
    private String propertyName;

    @Column(name = "type")
    @Enumerated(EnumType.STRING)
    private ItemType itemType;

    public ItemPropertyDefinition() {
    }

    public ItemPropertyDefinition(String propertyName, ItemType itemType) {
        this.propertyName = propertyName;
        this.itemType = itemType;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getPropertyName() {
        return propertyName;
    }

    public void setPropertyName(String propertyName) {
        this.propertyName = propertyName;
    }

    public ItemType getItemType() {
        return itemType;
    }

    public void setItemType(ItemType itemType) {
        this.itemType = itemType;
    }

    @Override
    public String toString() {
        return "ItemPropertyDefinition{" +
                "id=" + id +
                ", propertyName='" + propertyName + '\'' +
                ", itemType=" + itemType +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ItemPropertyDefinition that = (ItemPropertyDefinition) o;
        return id == that.id &&
                Objects.equals(propertyName, that.propertyName) &&
                Objects.equals(itemType, that.itemType);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, propertyName, itemType);
    }
}

最后是映射:

import javax.persistence.*;
import java.util.Objects;

@Entity
@Table(name = "item_properties")
public class ItemProperty {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "item_id")
    private Item item;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "item_property_definition_id")
    private ItemPropertyDefinition itemPropertyDefinition;

    @Column(name = "value")
    private String value;

    public ItemProperty(){}

    public ItemProperty(Item item, ItemPropertyDefinition itemPropertyDefinition, String value) {
        this.item = item;
        this.itemPropertyDefinition = itemPropertyDefinition;
        this.value = value;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Item getItem() {
        return item;
    }

    public void setItem(Item item) {
        this.item = item;
    }

    public ItemPropertyDefinition getItemPropertyDefinition() {
        return itemPropertyDefinition;
    }

    public void setItemPropertyDefinition(ItemPropertyDefinition itemPropertyDefinition) {
        this.itemPropertyDefinition = itemPropertyDefinition;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "ItemProperty{" +
                "id=" + id +
                ", item=" + item +
                ", itemPropertyDefinition=" + itemPropertyDefinition +
                ", value='" + value + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ItemProperty that = (ItemProperty) o;
        return id == that.id &&
                Objects.equals(item, that.item) &&
                Objects.equals(itemPropertyDefinition, that.itemPropertyDefinition) &&
                Objects.equals(value, that.value);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, item, itemPropertyDefinition, value);
    }
}

感谢您的提示。这是我第一次玩后端。

【问题讨论】:

  • 发生错误时,您能准确地写出您正在做什么吗?
  • @Andronicus 如果我有 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "item_id") 私人项目项目; ->> fetch type lazy 然后它发生,如果急切一切都好
  • 启动时还是执行查询时?
  • @Andronicus 执行查询时,我猜映射错误...
  • 那么请发布该查询。我需要确切地看到你在做什么。

标签: java json spring hibernate spring-data-jpa


【解决方案1】:

问题是您正在使用实体覆盖 toString()equals()hashCode() 方法。在这些函数中使用的所有内容都必须是与父实体一起加载的基本实体。这就是为什么在急切加载时没有抛出异常的原因。

一般情况下,我不建议使用子实体来确定相等性等,例如,这需要急切地加载它们,这对性能不利。出于性能考虑,我会让它们延迟加载并重写重写的方法,但如果您需要在这些方法中使用它们,则需要急切地加载它们。

Vlad Mihalcea 写了一篇关于实现 toString()equalshashCode() 的精彩 read

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 2011-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多