java - JPA mappedBy 引用了一个未知的目标实体
问题描述
我正在编写一个简单的库存数据库,其中包含产品、订单和客户表。数据库定义可以在这里找到:
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
我的实体和存储库类可以在下面找到:
产品.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;
}
订单.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<>();
}
我知道问题与实体之间的关系有关,但我一直无法找到解决方案。任何帮助将不胜感激。
解决方案
尝试纠正这一点:
@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;
}
请参阅文档中的其他说明。
你也应该更正你的Product
-Order
@ManyToMany
协会。只有该关联的一侧应该使用@JoinTable
另一侧应该使用注释mappedBy
的属性。@ManyToMany
像这样的东西:
@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<>();
}
正如文档中所述:
对于
@ManyToMany
关联,REMOVE
级联的实体状态转换没有意义,因为它会传播到链接表之外。由于另一方可能被父方的其他实体引用,因此自动删除可能以ConstraintViolationException
.
同样正如文档的本节中所解释的那样:
如果您忘记了
JOIN FETCH
所有EAGER
关联,Hibernate 将为每一个关联发出辅助选择,这反过来又会导致 N+1 查询问题。因此,您应该更喜欢 LAZY 关联。
推荐阅读
- java - Java Application connecting to PostgreSQL through Nginx proxying SSL
- python - 更快的代码来计算具有循环(周期性)边界条件的 numpy 数组中的点之间的距离
- c# - C# Selenium - 无法获取元素鼠标悬停的背景颜色
- c++ - Using std::transform to Add Vector of Vectors (A) to another Vector of Vectors (B)
- reactjs - 如何使用 create-react-app 正确配置 material-ui 进行测试?
- reactjs - 如何在 reactjs+webpack 的正文末尾呈现 javascript 文件?
- python - Separating nested for loops in list comprehensions
- f# - F# - 打印匹配表达式结果
- ejb - EJBs are getting duplicated in weblogic 12c using EAR deployment from jdeveloper 12c
- reactjs - 打开多个 Kendo Window React 包装器