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 引用了一个未知的目标实体的主要内容,如果未能解决你的问题,请参考以下文章
多对多 Spring MVC mappedBy 引用了一个未知的目标实体属性
java.lang.ExceptionInInitializerError 和 org.hibernate.AnnotationException: mappedBy 引用了一个未知的目标实体属性: