假设我们有两个实体,A和B. B与A有多对一的关系如下:
@Entity
public class A {
@OneToMany(mappedBy="a_id")
private List<B> children;
}
@Entity
public class B {
private String data;
}
Run Code Online (Sandbox Code Playgroud)
现在,我想删除A对象并将删除级联到其所有子对象(B).有两种方法可以做到这一点:
1)添加cascade=CascadeType.ALL, orphanRemoval=true
到OneToMany注释,让JPA在从数据库中删除A对象之前删除所有子项.
2)按原样保留类,只需让数据库级联删除即可.
使用后面的选项有什么问题吗?它会导致实体管理器保留对已删除对象的引用吗?我选择第二个选项的原因是选项一生成n + 1个SQL查询以进行删除,当对象A包含大量子节点时可能需要较长时间,而选项二只生成一个SQL查询然后继续愉快.对此有什么"最佳实践"吗?
是否有一个脚本可用于启用现有表的级联删除.谢谢.
我的数据库中有3个表:
如您所见,ProjectsTags表是一个桥表
这是我流利的nhibernate映射
ProjectMap.cs:
Map(x => x.Name).Not.Nullable();
HasMany(x => x.ProjectsTags).AsBag().Inverse()
.Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
Run Code Online (Sandbox Code Playgroud)
ProjectsTagsMap.cs:
References(x => x.Project).Not.Nullable();
References(x => x.Tag).Not.Nullable();
Run Code Online (Sandbox Code Playgroud)
TagMap.cs:
Map(x => x.Name).Not.Nullable();
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我历史上没有将Tag表链接到其他任何内容.我现在需要生成一个报告来显示Tag以及该标签的使用频率,因此我需要从Tag加入ProjectsTag.我尝试将此行添加到tagsmap中:
HasMany(x => x.ProjectsTags).AsBag().Inverse()
.Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
Run Code Online (Sandbox Code Playgroud)
但是当我去更新标签对象上的名称并提交时,我收到此错误:
拥有实体实例不再引用具有cascade ="all-delete-orphan"的集合
任何人都可以看到我添加的内容有什么问题,当我只是更新Tag表时会导致这个nhibernate异常.我的目标再次是能够做到这样的事情:
Tag.ProjectTags.Count();
Run Code Online (Sandbox Code Playgroud)
以下是一些额外的代码:
我的标签类:
public class Tag
{
public virtual IList<ProjectTag> ProjectTags { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
}
Run Code Online (Sandbox Code Playgroud) 我是EF的新手,并且为了方便删除我的对象而苦苦挣扎.我的两个对象和相关的DbContext如下所示:
public class Context: DbContext
{
public Context() : base(){}
public DbSet<Person> Persons {get;set;}
public DbSet<Vehicle> Vehicles {get;set;}
}
public class Person
{
public int PersonID {get;set;}
public string Name {get;set;}
}
public class Vehicle
{
public int VehicleID {get;set;}
public int? PersonID {get;set;}
[ForeignKey("PersonID")]
public virtual Person Person {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
如上所述,一个人可以链接到多个车辆.从人到车辆没有明确的链接,但是通过外键关系存在从车辆到"父母"人的链接.
然后我在我的代码中创建各种车辆,并将这些车辆链接到可选的人物对象(外键可以为空).
我的问题是删除Person对象.我通常会删除对象,如下所示:
private void DeletePerson()
{
using (var context = new Context())
{
int personID = 4; //Determined through other code
var person = context.Persons.Find(personID);
context.Persons.Remove(person); …
Run Code Online (Sandbox Code Playgroud) 我有一个名为"Customer"的对象,它将在其他表中用作外键.
问题是我想知道是否可以删除"客户"(即,它没有在任何其他表中引用).
Nhibernate有可能吗?
我正在使用Entity Framework 4并且在父实体和子实体之间具有一对多的关系.我正在尝试通过从父的子集合中删除它来删除使用父存储库的子节点:
public virtual void RemoveChild(Child child)
{
children.Remove(child);
}
Run Code Online (Sandbox Code Playgroud)
当我尝试保存更改时,我收到以下错误:
来自"ParentChild"AssociationSet的关系处于"已删除"状态.给定多重约束,相应的"Child"也必须处于"已删除"状态.
当然,我不必使用子存储库显式删除子实体!
愿有人帮助我.我正在尝试一些东西,但我(也)是(我的)SQL的新手.
我使用两个表:项目和类别.表项具有外键字段:category_id.
我希望表格类别保持整洁.因此,如果项目中的项目不属于类别中的类别X,则应从类别中删除类别X. 你是如何建立的.我通过使用DELETE ON CASCADE猜测,但到目前为止,当我从类别中删除类别时,它只删除了项目中的相应项目.
非常感谢帮助我!
我有两个普通表和一个关系表。
--------------------------------------------------
| Group | Membership | User |
| (ID, NAME) |(GRP_ID, U_ID) |(ID, FORENAME) |
--------------------------------------------------
| 1, Admin | 1, 1 | 1, Joe |
--------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
成员有两个外键
FK1 Membership.GRP_ID -> Group.ID
FK2 Membership.U_ID -> User.ID
Run Code Online (Sandbox Code Playgroud)
我可以设置cascade-delete
每个外键(FK1
和FK2
)。
如果既不删除FK1
也不FK2
删除级联,则我也无法删除Admin或Joe,因为它们保持“成员身份”连接。
--------------------------------------------------
| Group | Membership | User |
| (ID, NAME) |(GRP_ID, U_ID) |(ID, FORENAME) |
--------------------------------------------------
| 1, Admin | 1, 1 | 1, Joe |
--------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
我有一个叫做设备的表,还有8个我称之为equipment_child1的表,依此类推,直到equipment_child8.
所有表之间的commom字段是cod_equip,使用此字段我可以使用设备父表识别所有子设备表.
我需要在设备移动时从设备中删除数据,但我需要删除所有表equipment_child1到equipment_child8的数据.
然后我记得我在innoDB引擎中使用了DELETE CASCADE,但现在我正在使用MyISAM engina,这是一个问题吗?
任何帮助,都会澄清......
我有一个A
具有基本类型集合的实体(例如String
).我使用这样的映射,因为与每个实例关联的字符串A
依赖于A
生命周期.如果我想A
从DB中删除一个实例,我也希望String
删除它的关联s.
我的映射如下:
@Entity
public class A {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "name", nullable = false, unique = true)
private String name;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "AStrings", joinColumns = @JoinColumn(name = "id"))
@Column(name = "strings", nullable = false)
private Set<String> strings;
}
Run Code Online (Sandbox Code Playgroud)
如果我创建一个实例A
并添加一些字符串,那么我可以使用持久化实例Session.save(myInstance)
.实例A
及其关联的String
s都是持久的.
但是,如果我想从数据库中删除相同的实例,使用Session.createQuery("delete A a where a.name = ?").setString(0, name).executeUpdate()
,我得到一个外键约束错误:
无法删除或更新父行:外键约束失败
但是,我希望 …
sql ×3
c# ×2
cascade ×2
hibernate ×2
java ×2
mysql ×2
nhibernate ×2
eclipselink ×1
foreign-keys ×1
jpa ×1
jpa-2.0 ×1
many-to-many ×1
sql-server ×1
t-sql ×1