在 Doctrine2 实体中了解 "transitive persistence / cascade operations"
Understanding "transitive persistence / cascade operations" at Doctrine2 entities
我将开始 post 说我已经阅读了 docs 但相反的帮助我在这一点上更加困惑。
让我们用 ManyToOne
和 ManyToMany
关系获取一些实体(实际用例是我项目的一部分)。
// This is the main entrance point
class SolicitudUsuario
{
}
// Each SolicitudUsuario can have one|many ProductoSolicitud
class ProductoSolicitud
{
/**
* @var \SolicitudUsuario
*
* @ORM\ManyToOne(targetEntity="SolicitudUsuario", cascade={"persist"})
* @ORM\JoinColumn(name="solicitud_usuario_id", referencedColumnName="id")
*/
protected $solicitud_usuario;
/**
* @ORM\ManyToMany(targetEntity="CodigoArancelario", inversedBy="codigoArancelarioProducto", cascade={"persist"})
* @ORM\JoinTable(name="negocio.producto_codigo_arancelario", schema="negocio",
* joinColumns={@ORM\JoinColumn(name="producto_solicitud_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="codigo_arancelario_id", referencedColumnName="id")}
* )
*/
protected $productoCodigosArancelarios;
}
// Each ProductoSolicitud can have one|many MarcaProductoSolicitud
// Each ProductoSolicitud can have one|many ModeloProductoSolicitud
// Each ProductoSolicitud can have one|many FabricanteProductoSolicitud
class ModeloMarcaProducto
{
/**
* @ORM\ManyToOne(targetEntity="MarcaProductoSolicitud")
* @ORM\JoinColumn(name="marca_producto_id", referencedColumnName="id")
*/
protected $marca_producto;
/**
* @ORM\ManyToOne(targetEntity="ModeloProductoSolicitud")
* @ORM\JoinColumn(name="modelo_producto_id", referencedColumnName="id")
*/
protected $modelo_producto;
/**
* @ORM\ManyToOne(targetEntity="ProductoSolicitud")
* @ORM\JoinColumn(name="producto_solicitud_id", referencedColumnName="id")
*/
protected $producto_solicitud;
/**
* @ORM\ManyToMany(targetEntity="FabricanteProductoSolicitud", mappedBy="fabricanteModeloMarcaProducto", cascade={"persist"})
*/
protected $modeloMarcaProducto;
}
// Each FabricanteProductoSolicitud can have one|many FabricanteDistribuidor
// Each ProductoSolicitud can have one|many Pais
class FabricanteProductoSolicitud
{
/**
* @ORM\ManyToOne(targetEntity="FabricanteDistribuidor")
* @ORM\JoinColumn(name="fabricante_distribuidor_id", referencedColumnName="id")
*/
protected $fabricante_distribuidor;
/**
* @ORM\ManyToOne(targetEntity="ProductoSolicitud")
* @ORM\JoinColumn(name="producto_solicitud_id", referencedColumnName="id")
*/
protected $producto_solicitud;
/**
* @ORM\ManyToMany(targetEntity="Pais", inversedBy="fabricanteProductoSolicitudPais", cascade={"persist"})
* @ORM\JoinTable(name="nomencladores.pais_fabricante_producto_solicitud", schema="nomencladores",
* joinColumns={@ORM\JoinColumn(name="fabricante_producto_solicitud_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="pais_id", referencedColumnName="id")}
* )
*/
protected $paisesFabricanteProductoSolicitudPais;
/**
* @ORM\ManyToMany(targetEntity="ModeloMarcaProducto", inversedBy="modeloMarcaProducto", cascade={"persist"})
* @ORM\JoinTable(name="negocio.fabricante_modelo_marca_producto", schema="negocio",
* joinColumns={@ORM\JoinColumn(name="fabricante_producto_solicitud_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="modelo_marca_producto_id", referencedColumnName="id")}
* )
*/
protected $fabricanteModeloMarcaProducto;
}
现在,我想删除一个SolicitudUsuario
。拥有如上所示的实体,我需要手动处理每个依赖实体吗?正确的?这是一种疯狂的原因,可以管理很少的实体,但管理大量实体将是一件痛苦的事情!
我的问题是如果我将 cascade={"persist", "remove"}
添加到 ManyToOne
和 ManyToMany
关系会发生什么?如果我删除第一个 SolicitudUsuario
是否应该删除其余的级联?
任何人都可以指出正确的方向并给我一个很好的解释吗?
为避免循环,您可以使用数据库级别cascade delete。将映射更改为:
/**
* @ORM\ManyToOne(targetEntity="ProductoSolicitud")
* @ORM\JoinColumn(name="producto_solicitud_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $producto_solicitud;
或使用DQL bulk delete,如
$q = $em->createQuery("delete from Name\Space\FacturaProductoSolicitud f where f.producto_solicitud= some_id")
->execute();
还有其他选择,但我认为这两个是最有效的。
我将开始 post 说我已经阅读了 docs 但相反的帮助我在这一点上更加困惑。
让我们用 ManyToOne
和 ManyToMany
关系获取一些实体(实际用例是我项目的一部分)。
// This is the main entrance point
class SolicitudUsuario
{
}
// Each SolicitudUsuario can have one|many ProductoSolicitud
class ProductoSolicitud
{
/**
* @var \SolicitudUsuario
*
* @ORM\ManyToOne(targetEntity="SolicitudUsuario", cascade={"persist"})
* @ORM\JoinColumn(name="solicitud_usuario_id", referencedColumnName="id")
*/
protected $solicitud_usuario;
/**
* @ORM\ManyToMany(targetEntity="CodigoArancelario", inversedBy="codigoArancelarioProducto", cascade={"persist"})
* @ORM\JoinTable(name="negocio.producto_codigo_arancelario", schema="negocio",
* joinColumns={@ORM\JoinColumn(name="producto_solicitud_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="codigo_arancelario_id", referencedColumnName="id")}
* )
*/
protected $productoCodigosArancelarios;
}
// Each ProductoSolicitud can have one|many MarcaProductoSolicitud
// Each ProductoSolicitud can have one|many ModeloProductoSolicitud
// Each ProductoSolicitud can have one|many FabricanteProductoSolicitud
class ModeloMarcaProducto
{
/**
* @ORM\ManyToOne(targetEntity="MarcaProductoSolicitud")
* @ORM\JoinColumn(name="marca_producto_id", referencedColumnName="id")
*/
protected $marca_producto;
/**
* @ORM\ManyToOne(targetEntity="ModeloProductoSolicitud")
* @ORM\JoinColumn(name="modelo_producto_id", referencedColumnName="id")
*/
protected $modelo_producto;
/**
* @ORM\ManyToOne(targetEntity="ProductoSolicitud")
* @ORM\JoinColumn(name="producto_solicitud_id", referencedColumnName="id")
*/
protected $producto_solicitud;
/**
* @ORM\ManyToMany(targetEntity="FabricanteProductoSolicitud", mappedBy="fabricanteModeloMarcaProducto", cascade={"persist"})
*/
protected $modeloMarcaProducto;
}
// Each FabricanteProductoSolicitud can have one|many FabricanteDistribuidor
// Each ProductoSolicitud can have one|many Pais
class FabricanteProductoSolicitud
{
/**
* @ORM\ManyToOne(targetEntity="FabricanteDistribuidor")
* @ORM\JoinColumn(name="fabricante_distribuidor_id", referencedColumnName="id")
*/
protected $fabricante_distribuidor;
/**
* @ORM\ManyToOne(targetEntity="ProductoSolicitud")
* @ORM\JoinColumn(name="producto_solicitud_id", referencedColumnName="id")
*/
protected $producto_solicitud;
/**
* @ORM\ManyToMany(targetEntity="Pais", inversedBy="fabricanteProductoSolicitudPais", cascade={"persist"})
* @ORM\JoinTable(name="nomencladores.pais_fabricante_producto_solicitud", schema="nomencladores",
* joinColumns={@ORM\JoinColumn(name="fabricante_producto_solicitud_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="pais_id", referencedColumnName="id")}
* )
*/
protected $paisesFabricanteProductoSolicitudPais;
/**
* @ORM\ManyToMany(targetEntity="ModeloMarcaProducto", inversedBy="modeloMarcaProducto", cascade={"persist"})
* @ORM\JoinTable(name="negocio.fabricante_modelo_marca_producto", schema="negocio",
* joinColumns={@ORM\JoinColumn(name="fabricante_producto_solicitud_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="modelo_marca_producto_id", referencedColumnName="id")}
* )
*/
protected $fabricanteModeloMarcaProducto;
}
现在,我想删除一个SolicitudUsuario
。拥有如上所示的实体,我需要手动处理每个依赖实体吗?正确的?这是一种疯狂的原因,可以管理很少的实体,但管理大量实体将是一件痛苦的事情!
我的问题是如果我将 cascade={"persist", "remove"}
添加到 ManyToOne
和 ManyToMany
关系会发生什么?如果我删除第一个 SolicitudUsuario
是否应该删除其余的级联?
任何人都可以指出正确的方向并给我一个很好的解释吗?
为避免循环,您可以使用数据库级别cascade delete。将映射更改为:
/**
* @ORM\ManyToOne(targetEntity="ProductoSolicitud")
* @ORM\JoinColumn(name="producto_solicitud_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $producto_solicitud;
或使用DQL bulk delete,如
$q = $em->createQuery("delete from Name\Space\FacturaProductoSolicitud f where f.producto_solicitud= some_id")
->execute();
还有其他选择,但我认为这两个是最有效的。