在这里,我们将给大家分享关于@ManyToOneJPA关联和级联…不确定删除对象会发生什么的知识,同时也会涉及到如何更有效地@ManyToMany/@OneToManymappingby属性用于双向关
在这里,我们将给大家分享关于@ManyToOne JPA关联和级联…不确定删除对象会发生什么的知识,同时也会涉及到如何更有效地@ ManyToMany / @ OneToMany mappingby属性用于双向关联、@ManyToOne JPA 关联的 CascadeType.ALL 是什么意思、@ManyToOne JPA关系可以为空吗?、@OneToMany、@ManyToOne以及@ManyToMany讲解(五)的内容。
本文目录一览:- @ManyToOne JPA关联和级联…不确定删除对象会发生什么
- @ ManyToMany / @ OneToMany mappingby属性用于双向关联
- @ManyToOne JPA 关联的 CascadeType.ALL 是什么意思
- @ManyToOne JPA关系可以为空吗?
- @OneToMany、@ManyToOne以及@ManyToMany讲解(五)
@ManyToOne JPA关联和级联…不确定删除对象会发生什么
对于删除操作中级联的工作方式,我仍然不太清楚。我想知道如果我有这个会发生什么:
class myBean{ @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) public Cliente getClienteDiAppartenenza() { return clienteDiAppartenenza; }}class Cliente{@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) public List<myBean> getMyBeans() { return myBeans; }}
如果我删除具有此属性的myBean,我不确定链接的Cliente是否也会被删除(很奇怪),或者Cliente内部的集合将被更新,并且myBean的实例将被删除,然后保存。
会发生什么??Hibernato文档对此不太清楚…
答案1
小编典典这不是Hibernate,这是JPA 2.0标准的一部分。注释中有两个方面,一件事是使用orphanRemoval。
当父实体控制子实体的创建和销毁时,可以使用orphanRemoval。在UML中,这是组成的情况,这是整个部分的强大所有权和一致的生命周期。JPA
2.0规范在第2.9节:实体关系中说:
指定为OneToOne或OneToMany的关联支持使用orphanRemoval选项。当orphanRemoval生效时,将发生以下行为:
1.
如果从关系中移除了作为关系目标的实体(通过将关系设置为null或从关系集合中移除实体),则移除操作将应用于孤立的实体。清除操作在冲洗操作时应用。orphanRemoval功能适用于其父实体“私有”拥有的实体。否则,可移植应用程序不得依赖于特定的删除顺序,并且不得将已孤立的实体重新分配给另一个关系,也不能尝试将其持久化。如果孤立的实体是分离的,新的或已删除的实体,则orphanRemoval的语义不适用。
- 如果将删除操作应用于托管源实体,则删除操作将根据3.2.3节的规则级联到关系目标(因此,不必为该关系指定cascade = REMOVE)[
20]。
第二个方面是在没有隐式删除的情况下使用cascase = REMOVE。
第3.2.3节:删除包含有关删除过程的详细信息:
应用于实体X的remove操作的语义如下:
•如果X是新实体,则删除操作将忽略它。但是,如果从X到这些其他实体的关系用cascade = REMOVE或cascade =
ALL标注元素值标注,则移除操作将层叠到X引用的实体。•如果X是一个受管实体,则删除操作会使它被删除。如果从X到这些其他实体的关系使用层叠= REMOVE或层叠=
ALL标注元素值标注,则remove操作将层叠到X引用的实体。•如果X是一个分离的实体,则remove操作将引发IllegalArgumentException(否则事务提交将失败)。
•如果X是已删除的实体,则删除操作将忽略它。
在事务提交之时或之前,或者由于刷新操作,将从数据库中删除已删除的实体X。删除实体后,其状态(生成状态除外)将是实体在调用删除操作时的状态。
@ ManyToMany / @ OneToMany mappingby属性用于双向关联
我正在为我的实习工作开发JPA兼容套件…该套件的一部分涉及测试极端情况的正确实现。
@ManyToMany
具有mapedBy属性。JPA指出:
字符串mappingBy-拥有关系的字段或属性。除非关系是单向的,否则为必需。
没有给出默认值-默认列为空。
给定双向@ManyToMany
-此示例来自JPA 2.0 JSR-317规范本身!
顾客
@ManyToMany@JoinTable(name="CUST_PHONES")public Set<PhoneNumber> getPhones() { return phones; }
电话号码
@ManyToMany(mappedBy="phones")public Set<Customer> getCustomers() { return customers; }
尚未在@ManyToMany
of的中定义mapledBy属性Customer
!我不知道的双向映射有默认值吗?
我查看了类似的情况,发现: @OneToOne
-mappingBy是可选的,没有默认值@OneToMany
-完全相同@ManyToMany
(mappedBy对于双向是可选的,没有默认值)
简而言之,我的问题是:
对于@ManyToMany
和@OneToMany
,应在关系的拥有方(Customer
例如)中将其放置在mappedBy属性中?
答案1
小编典典这绝不是一个极端的情况。每个双向关联都有一个所有者方和一个反向方。
JPA使用拥有方来确定两个实体之间是否存在关联。另一侧被忽略。
拥有方定义了如何映射关联(使用JoinColumn,JoinTable等批注)。它没有任何mappedBy
属性。
反面使用该mappedBy
属性说:“嘿,我只是由以下属性映射的那个的逆关联”。
因此,根据定义,拥有方没有mappedBy
属性。如果有一个,它就不会是拥有者。
JPA规范对此做了很好的解释。如果您需要为此规范构建兼容套件,则最好阅读并理解它。
我真的看不出编写这种兼容工具包的意义,因为正如在JPA2
JSR主页上所写的那样,
- 根据Java规范参与协议(JSPA)的要求,Java Persistence API版本2.0
- TCK将免费获得许可,无需支持合格的非营利实体。此类资格将由兼容性测试奖学金计划进行验证。经奖学金委员会批准,也可以免费提供支持。有关更多信息,请访问:http
- //java.sun.com/scholarship/。
@ManyToOne JPA 关联的 CascadeType.ALL 是什么意思
我想我误解了在关系中级联的含义@ManyToOne
。
案子:
public class User { @OneToMany(fetch = FetchType.EAGER) protected Set<Address> userAddresses;}public class Address { @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) protected User addressOwner;}
的含义是cascade = CascadeType.ALL
什么?例如,如果我从数据库中删除某个地址,我添加的事实如何cascade =CascadeType.ALL
影响我的数据(User
我猜是)?
答案1
小编典典的含义CascadeType.ALL
是持久性将传播(级联)所有EntityManager
操作(PERSIST, REMOVE, REFRESH,MERGE, DETACH
)到相关实体。
在您的情况下,这似乎是一个坏主意,因为删除 anAddress
会导致删除相关的User
.
由于用户可以拥有多个地址,因此其他地址将成为孤立地址。但是,相反的情况(注释User
)将有意义 -
如果地址仅属于单个用户,则在删除该用户时传播属于该用户的所有地址的删除是安全的。
顺便说一句:您可能希望向mappedBy="addressOwner"
您添加一个属性,User
以向持久性提供程序发出连接列应该在 ADDRESS
表中的信号。
@ManyToOne JPA关系可以为空吗?
如何解决@ManyToOne JPA关系可以为空吗??
您需要设置:
@ManyToOne(optional = true, fetch = FetchType.LAZY)
不optional=false
。
该@Column(nullable=true)
是指示DDL生成工具,包括NULL
sql列类型约束。
解决方法
我有一个表具有另一个表的外键(许多关系),但我希望它可以为空。
像这样:
public class SubType() {
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid",strategy = "uuid")
private String id;
}
public class TopUp {
@Column(nullable = true)
@ManyToOne(optional = false,fetch = FetchType.LAZY)
private SubType subType;
}
但是@Column(nullable =
true)
抛出NullPointerException
和表示子类型不能为null。有什么办法可以使ManyToOne接受null?
@OneToMany、@ManyToOne以及@ManyToMany讲解(五)
一、一对多(@OneToMany)
1、单向一对多模型
假设通过一个客户实体可以获得多个地址信息。
对于一对多的实体关系而言,表结构有两种设计策略,分别是外键关联和表关联。
(1) 映射策略---外键关联
在数据库中表customer和表结构address定义,如下:
create table customer (
id int(20) not null auto_increment,
name varchar(100),
primary key(id)
)
create table address (
id int(20) not null auto_increment,
province varchar(50),
city varchar(50),
postcode varchar(50),
detail varchar(50),
customer_id int(20),
primary key (id)
)
注意此时外键定义在多的一方,也就是address表中。
此时,表customer映射为实体CustomerEO,代码如下:
@Entity
@Table(name="customer")
public class CustomerEO implements java.io.Serializable {
@OneToMany(cascade={ CascadeType.ALL })
@JoinColumn(name="customer_id")
private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
...
}
注释@OneToMany的定义代码如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToMany {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default LAZY;
String mappedBy() default "";
}
使用时要注意一下几点问题:
a、targetEntity属性表示默认关联的实体类型。如果集合类中指定了具体类型了,不需要使用targetEntity.否则要指定targetEntity=AddressEO.class。
b、mappedBy属性用于标记当实体之间是双向时使用。
(2) 映射策略---表关联
在上面address表中去掉customer_id字段,在增加一个表ref_customer_address,如下:
--客户地址关系表
create table ref_customer_address (
customer_id int(20) not null,
address_id int(20) not null unique
)
此时表customer映射为CustomerEO实体,代码如下:
@Entity
@Table(name = "customer")
public class CustomerEO implements java.io.Serializable {
...
@OneToMany(cascade = { CascadeType.ALL })
@JoinTable(name="ref_customer_address",
joinColumns={ @JoinColumn(name="customer_id",referencedColumnName="id")},
inverseJoinColumns={@JoinColumn(name="address_id",referencedColumnName="id")})
private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
...
}
表关联@JoinTable,定义如下:
@Target({METHOD,FIELD})
public @interface JoinTable {
String name() default "";
String catalog() default "";
String schema() default "";
JoinColumn[] joinColumns() default {};
JoinColumn[] inverseJoinColumns() default {};
UniqueConstraint[] uniqueConstraints default {};
}
其中:
a、该标记和@Table相似,用于标注用于关联的表。
b、name属性为连接两张表的表名。默认的表名为:“表名1”+“-”+“表名2”,上面例子默认的表名为customer_address。
c、joinColumns属性表示,在保存关系中的表中,所保存关联的外键字段。
d、inverseJoinColumns属性与joinColumns属性类似,不过它保存的是保存关系的另一个外键字段。
(3) 默认关联
在数据库底层为两张表添加约束,如下:
create table customer_address (
customer_id int(20) not null,
address_id int(20) not null unique
)
alter table customer_address add constraint fk_ref_customer foreign key (customer_id) references customer (id);
alter table customer_address add constraint fk_ref_address foreign key (address_id) references address (id);
这样,在CustomerEO中只需要在标注@OneToMany即可!
二、多对一@ManyToOne
1、单向多对一模型。
(1) 外键关联
配置AddressEO实体如下:
@Entity
@Table(name="address")
public class AddressEO implements java.io.Serializable {
@ManyToOne(cascade = { CascadeType.ALL })
@JoinColumn(name="customer_id")
private CustomerEO customer;
// ...
}
@ManyToOne定义如下:
@Target({METHOD,FIELD}) @Retention(RUNTIME)
public @interface ManyToOne {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fatch() default EAGER;
boolean optional() default true;
}
(2) 默认关联
数据库脚本定义的相关字段的约束,创建外键后,直接使用@ManyToOne
三、高级一对多和多对一映射
即双向关联模型,确定了双向关联后,多的一方AddressEO不变使用@ManyToOne,而CustomerEO实体修改为:
@Entity
@Table(name="customer")
public class CustomerEO {
@OneToMany(mappedBy="customer")
private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
// ...
}
其中,@OneToMany标记中的mappedBy属性的值为AddressEO实体中所引用的CustomerEO实体的属性名。
四、多对多(@ManyToMany)
和一对多类型,不在赘述。@ManyToMany标记的定义如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface ManyToMany {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fecth() default LAZY;
String mappedBy() default "";
}
五、最后,谈谈关于集合类的选择
在映射关系中可以使用的集合类有Collection、Set、List和Map,下面看下如何选择。
1、定义时使用接口,初始化使用具体的类。
如Collection可以初始化为ArrayList或HashSet;
Set可以初始化为HashSet;
List可以初始化为ArrayList;
Map可以初始化为HashMap.
2、集合类的选择
Collection类是Set和List的父类,在未确定使用Set或List时可使用;
Set集合中对象不能重复,并且是无序的;
List集合中的对象可以有重复,并且可以有排序;
Map集合是带有key和value值的集合。
今天关于@ManyToOne JPA关联和级联…不确定删除对象会发生什么的分享就到这里,希望大家有所收获,若想了解更多关于@ ManyToMany / @ OneToMany mappingby属性用于双向关联、@ManyToOne JPA 关联的 CascadeType.ALL 是什么意思、@ManyToOne JPA关系可以为空吗?、@OneToMany、@ManyToOne以及@ManyToMany讲解(五)等相关知识,可以在本站进行查询。
本文标签: