让我们说我有两个表 - "孩子"和"父母"有多对一的关系.如果父记录被删除,我需要删除子条目.
如果我通过在parent.hbm中创建一对多关联并设置cascade ="all-delete-orphan"来链接子表,则不会出现问题.
问题是我不希望在父方面有一对多关系,所以我在子方面创建了多对一关系.原因是子表非常大,我不想每次使用父表时提取数百条记录.所以我的配置如下所示:
child.hbm:
<many-to-one name="parent" class="com.example.Parent" column="parentid"/>
Run Code Online (Sandbox Code Playgroud)
而parent.hbm与child没有关联.
问题是:如果子项链接到具有多对一的父项,如何在删除父项时从子表中删除Hibernate记录?
谢谢.
我正在尝试创建一个应用程序,通过观察所有更改,然后立即将对象保存在问题中,使对象模型与数据库保持同步.模型中的许多对象在大型列表或树中都有子项.
当我从数据库加载一个对象时,我依靠单向级联关系来检索它的所有子对象并将它们包含在应用程序中.
但是,可以更改父对象中需要持久性的字段,并且可以确定没有子节点受到影响.所以我想坚持父母,而不是在所有级联的孩子坚持下去的数据库.
例如
@Entity
public class Parent {
@OneToMany(cascade=CascadeType.ALL)
public List children;
}
Run Code Online (Sandbox Code Playgroud)
当我持久保存Parent对象时,如何覆盖级联选项?或者我应该将其设置为REFRESH并确保我永远不需要级联持续存在?
我在Company类和CompanySettings类之间有一对一的关系.当我创建一个新的Company对象时,(在Company的构造函数中为其Settings属性创建了一个CompanySettings对象),然后
SaveOrUpdate(session, companyObject)
Run Code Online (Sandbox Code Playgroud)
我希望INSERT从公司级联到CompanySettings.但是,除非我在CompanySettings对象上明确调用SaveOrUpdate,否则不会发生这种情况.
映射文件如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"`>
<class name="AST.Domain.Company, AST.Domain" table="Companies">
<id name="EntityID" column="CompanyId">
<generator class="guid.comb" />
</id>
<property name="CompanyName" />
. . .
<one-to-one name="Settings" class="AST.Domain.CompanySettings, AST.Domain"
constrained="true" lazy="false" />
</class>
</hibernate-mapping>
Run Code Online (Sandbox Code Playgroud)
我的公司设置类的映射文件:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="AST.Domain.CompanySettings, AST.Domain" table="CompanySettings">
<id name="EntityID" column="CompanyId">
<generator class="foreign">
<param name="property">Company</param>
</generator>
</id>
<property name="MaxUsers" />
<one-to-one name="Company" class="AST.Domain.Company, AST.Domain" />
</class>
</hibernate-mapping>
Run Code Online (Sandbox Code Playgroud) 这里有点沮丧.我正在尝试找到一种方法来支持实体框架的更新级联,并且似乎没有内置方式.对网络的研究基本上表明每个人都说你永远不应该改变主键值,但是有一些有效的情况你需要(例如UPC值作为主键,而UPC条形码现在变得更大,这意味着更新现有的和保持适当的外键关系).
一种方法显然是利用SavingChanges事件,查看主键字段是否正在更改,如果是,则遍历导航属性并以这种方式更新子表.
从理论上讲,这可行.但这听起来很麻烦.谁有更好的主意?不能相信比尔会因为大多数人不这样做而将这些东西排除在框架之外.SQL Server仍然支持它...
谢谢!
entity-framework cascade foreign-key-relationship navigation-properties
我有对象A和B.
对象A就像
class A{
Set<B>
}
Run Code Online (Sandbox Code Playgroud)
现在当我保存AI时,希望Set<B>A 中的所有对象都自动保存在DB中.我该怎么做?
Oracle使用EclipseLink:
我在父(工作流)和孩子(阶段)之间有一对多的关系.在数据库中,我有一个删除约束,以便在工作流删除阶段删除.这从sqlplus工作正常.
class Workflow {
@Override
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "workflow", targetEntity = Stage.class)
@JoinColumn(name = "WORKFLOW_ID")
public Set<Stage> getStages() {
return m_stages;
}
}
class Stage {
@Override
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false, targetEntity = Workflow.class)
@JoinColumn(name = "WORKFLOW_ID", nullable = false)
public Workflow getWorkflow() {
return m_workflow;
}
}
Run Code Online (Sandbox Code Playgroud)
当我在@Transactional(propagation = Propagation.REQUIRED)方法中按名称加载工作流程然后em.remove(工作流程)该对象时,
我得到例外,例如
Error Code: 1407
Call: UPDATE STAGES SET WORKFLOW_ID = ?, FAILURE_STAGE_ID = ?, SUCCESS_STAGE_ID = ? WHERE …Run Code Online (Sandbox Code Playgroud) 合并一个具有相关实体的实体与关系设置为级联的持久化和合并操作后,关系就会丢失!
以下是实体:
class Event implements NormalizableInterface
{
/**
* @ORM\ManyToMany(targetEntity="Participant", inversedBy="events", cascade={"persist", "merge"})
* @ORM\JoinTable(name="event_participant",
* joinColumns={@ORM\JoinColumn(name="event_id", referencedColumnName="id", onDelete="CASCADE")},
* inverseJoinColumns={@ORM\JoinColumn(name="participant_id", referencedColumnName="id", onDelete="CASCADE")}
* )
*/
private $participants;
}
class Participant implements NormalizableInterface
{
/**
* @ORM\ManyToMany(targetEntity="Event", mappedBy="participants", cascade={"persist", "merge"})
*/
protected $events;
}
Run Code Online (Sandbox Code Playgroud)
这是我的加入:
foreach ($events as $event)
{
if (!$event->hasParticipant($participant)) {
$event->addParticipant($participant);
}
if (!$participant->hasEvent($event)) {
$participant->addEvent($event);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的合并代码:
echo "Before merge participant count: ".count($event->getParticipants()).PHP_EOL;
$event = $em->merge($event);
echo "After merge participant count: ".count($event->getParticipants()).PHP_EOL;
Run Code Online (Sandbox Code Playgroud)
......这是输出:
Before merge …Run Code Online (Sandbox Code Playgroud) 我有一个扩展使用NetBeans GUI编辑器构建的javax.swing.JFrame的类。当几个JFrame被打开时,是否有办法使其级联?
我花了很多时间试图弄清楚如何在SQL Server上为递归主键实现CASCADE ON DELETE一段时间了.我已经阅读了有关触发器,创建临时表等的信息,但还没有找到适用于我的数据库设计的答案.
这是一个Boss/Employee数据库示例,可用于演示目的:
TABLE employee
id|name |boss_id
--|---------|-------
1 |John |1
2 |Hillary |1
3 |Hamilton |1
4 |Scott |2
5 |Susan |2
6 |Seth |2
7 |Rick |5
8 |Rachael |5
Run Code Online (Sandbox Code Playgroud)
如您所见,每位员工都有一名也是员工的老板.所以,id/boss_id上存在PK/FK关系.
这是一个(缩写)表及其信息:
TABLE information
emp_id|street |phone
------|-----------|-----
2 |blah blah |blah
6 |blah blah |blah
7 |blah blah |blah
Run Code Online (Sandbox Code Playgroud)
employee.id/information.emp_id上有一个带有CASCADE ON DELETE的PK/FK.
例如,如果Rick被解雇,我们会这样做:
DELETE FROM employee WHERE id=7
Run Code Online (Sandbox Code Playgroud)
这应该从员工和信息中删除Rick的行.Yay级联!
现在,说我们经历了艰难时期,我们需要奠定汉密尔顿和他的整个部门.这意味着我们需要删除
我们运行时从员工和信息表中:
DELETE FROM employee WHERE id=3 …Run Code Online (Sandbox Code Playgroud) 假设我有三个模型:
我的关联设置如下:
Task.hasMany(TaskListEntry, {onDelete: 'cascade', hooks: true}));
TaskList.hasMany(TaskListEntry, {onDelete: 'cascade', hooks: true});
TaskListEntry.belongsTo(TaskList);
TaskListEntry.belongsTo(Task);
Run Code Online (Sandbox Code Playgroud)
除删除外,此方法工作正常。当我删除任务时,所有关联的TaskListEntries都会按预期方式删除。但是,当我删除TaskList时,其关联的TaskListEntries只是将其对TaskList的外键设置为null。
似乎Sequelize正在生成下表:
CREATE TABLE `TaskListEntries`(
`id` UUID PRIMARY KEY,
/* some other fields here */
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NOT NULL,
`TaskId` UUID REFERENCES `Tasks`(`id`) ON DELETE CASCADE ON UPDATE CASCADE,
`TaskListId` UUID REFERENCES `TaskLists`(`id`) ON DELETE SET NULL ON UPDATE CASCADE);
Run Code Online (Sandbox Code Playgroud)
尽管关联配置相同,但是Task和TaskList的外键具有不同的DELETE行为。如果我删除其中一个关联,则其他关联正常。
因此,我认为问题是使用多个外键ON DELETE CASCADE,至少就Sequelize而言是如此。
关于如何纠正这个问题有什么想法吗?
cascade ×10
java ×5
database ×2
hibernate ×2
jpa ×2
sql ×2
constraints ×1
doctrine-orm ×1
eclipselink ×1
foreign-keys ×1
insert ×1
jframe ×1
many-to-many ×1
mapping ×1
merge ×1
mysql ×1
nhibernate ×1
one-to-one ×1
persistence ×1
recursion ×1
save ×1
sequelize.js ×1
sql-server ×1
sqlite ×1
swing ×1
symfony ×1