JPA mappedBy 引用了一个未知的目标实体

Posted

技术标签:

【中文标题】JPA mappedBy 引用了一个未知的目标实体【英文标题】:JPA mappedBy reference an unknown target entity 【发布时间】:2021-05-02 09:50:14 【问题描述】:

我正在编写一个简单的库存数据库,其中包含产品、订单和客户表。数据库定义可以在这里找到:

CREATE TABLE public.customers
(
    id integer NOT NULL DEFAULT nextval('customers_id_seq'::regclass),
    title character varying(10) COLLATE pg_catalog."default" NOT NULL,
    first_name character varying(50) COLLATE pg_catalog."default" NOT NULL,
    middle_names character varying(50) COLLATE pg_catalog."default",
    last_name character varying(50) COLLATE pg_catalog."default" NOT NULL,
    email character varying(50) COLLATE pg_catalog."default" NOT NULL,
    phone_number character varying(50) COLLATE pg_catalog."default" NOT NULL,
    CONSTRAINT customers_pkey PRIMARY KEY (id)
)

CREATE TABLE public.products
(
    id integer NOT NULL DEFAULT nextval('products_id_seq'::regclass),
    name character varying(100) COLLATE pg_catalog."default" NOT NULL,
    sku integer NOT NULL,
    inventory_on_hand integer NOT NULL,
    reorder_threshold integer NOT NULL,
    price numeric(5,2),
    inventory_to_be_shipped integer NOT NULL,
    CONSTRAINT products_pkey PRIMARY KEY (id)
)

CREATE TABLE public.order_items
(
    id integer NOT NULL DEFAULT nextval('order_items_id_seq'::regclass),
    product_id integer NOT NULL,
    order_id integer NOT NULL,
    CONSTRAINT order_items_pkey PRIMARY KEY (id),
    CONSTRAINT order_items_order_id_fkey FOREIGN KEY (order_id)
        REFERENCES public.orders (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,
    CONSTRAINT order_items_product_id_fkey FOREIGN KEY (product_id)
        REFERENCES public.products (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)

CREATE TABLE public.orders
(
    id integer NOT NULL DEFAULT nextval('orders_id_seq'::regclass),
    customer_id integer,
    order_date date NOT NULL DEFAULT now(),
    arrival_date date,
    CONSTRAINT orders_pkey PRIMARY KEY (id),
    CONSTRAINT orders_customer_id_fkey FOREIGN KEY (customer_id)
        REFERENCES public.customers (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)

我正在尝试实现一个 Spring Security 资源服务器来对数据库执行 CRUD 操作。我已经为数据库中的每个表实现了实体类,但是当尝试启动服务器时,我得到了一个

org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: edu.finalyearproject.imsresourceserver.models.Order.customers in edu.finalyearproject.imsresourceserver.models.Customer.orders

我的实体和存储库类可以在下面找到:

Product.java:

@Entity
@Table(name = "products")
@Data
public class Product

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private Integer sku;
    private Float price;
    private Integer inventory_on_hand;
    private Integer reorder_threshold;

    @ManyToMany(cascade = CascadeType.PERSIST, CascadeType.MERGE, fetch = FetchType.LAZY)
    @JoinTable(
            name = "order_items",
            joinColumns = @JoinColumn(name = "product_id"),
            inverseJoinColumns = @JoinColumn(name = "order_id")
    )
    private Set<Order> orders = new HashSet<>();

客户.java

@Entity
@Table(name = "customers")
@Data
public class Customer

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;
    private String title;
    private String first_name;
    private String middle_names;
    private String last_name;
    private String email;
    private String phone_number;

    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Order> orders;

Order.java

@Entity
@Table(name = "orders")
@Data
public class Order

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne
    @JoinColumn(name="customer_id", nullable=false)
    private Customer customer;

    private Date order_date;

    private Date arrival_date;

    @ManyToMany(mappedBy = "orders", cascade = CascadeType.PERSIST, CascadeType.MERGE)
    private Set<Product> products = new HashSet<>();

我知道问题与实体之间的关系有关,但我一直无法找到解决方案。任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

尝试纠正这个问题:

@Entity
public class Customer

    // ...

    @OneToMany(mappedBy = "orders", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Order> orders;

到这里:

@Entity
public class Customer

    // ...

    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Order> orders;

请参阅documentation 中的其他说明。

您还应该更正您的 Product-Order @ManyToMany 关联。此关联只有一侧应使用@JoinTable,另一侧应使用@ManyToMany 注释的mappedBy 属性。像这样的:

@Entity
public class Product

    // ...

    @ManyToMany(
       cascade = CascadeType.PERSIST, CascadeType.MERGE,
       fetch = FetchType.LAZY
    )
    @JoinTable(
            name = "order_items",
            joinColumns = @JoinColumn(name = "product_id"),
            inverseJoinColumns = @JoinColumn(name = "order_id")
    )
    private Set<Order> orders = new HashSet<>();


@Entity
public class Order

    // ...

    @ManyToMany(
       mappedBy = "orders",
       cascade = CascadeType.PERSIST, CascadeType.MERGE,
       fetch = FetchType.LAZY)
    private Set<Product> products = new HashSet<>();

正如documentation中所述:

对于@ManyToMany 关联,REMOVE 实体状态转换没有意义级联,因为它会传播到链接表之外。由于另一端可能被父端的其他实体引用,因此自动删除可能会以ConstraintViolationException 结束。

正如this section of the documentation 中解释的那样:

如果您忘记 JOIN FETCH 所有 EAGER 关联,Hibernate 将为每个关联发出辅助选择,这反过来可能导致 N+1 查询问题。

因此,您应该更喜欢 LAZY 关联。

【讨论】:

您好,感谢您的评论!我已经按照你的建议修改了我的实体类,但我仍然收到mappedBy reference an unknown target entity property: edu.finalyearproject.imsresourceserver.models.Order.customer in edu.finalyearproject.imsresourceserver.models.Customer.orders 我已经更新了代码 sn-ps 以显示更改 看起来你使用mappedBy = "customers"但你应该使用mappedBy = "customer" 再次感谢@SternK 的回复,我正在使用 mappedBy = "customer" 但我仍然遇到同样的异常,我想知道我是否需要按顺序为客户添加注释.java?当我在 Order.java 中包含 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="customer_id", nullable=false) private Customer customer; 时,我得到一个 PropertyReferenceException: No property first found for type Customer! 你的异常说:mappedBy 引用了一个未知的目标实体属性:edu.finalyearproject.imsresourceserver.models.Order.customers 这绝对表明您在@987654344 中使用了mappedBy = "customers" @请重新检查。请提供实际的异常堆栈跟踪。 好的,你是 100% 正确的,你的解决方案如你所说,我出错的地方是我删除了加入 Order.java 中列的客户属性,因为你没有将它包含在你的解决方案中我错误地认为它需要被删除。我在下一条评论中提到的第二个异常是由我的 CustomerRepository 中有一个不正确的方法引起的另一个问题。感谢大家的帮助!

以上是关于JPA mappedBy 引用了一个未知的目标实体的主要内容,如果未能解决你的问题,请参考以下文章

: mappedBy 引用了一个未知的目标实体属性

多对多 Spring MVC mappedBy 引用了一个未知的目标实体属性

java.lang.ExceptionInInitializerError 和 org.hibernate.AnnotationException: mappedBy 引用了一个未知的目标实体属性:

询问休眠:错误:mappedBy 引用未知的目标实体属性

OnetoOne 未知映射者

未知实体 JPA Netbeans