【问题标题】:Doctrine one-to-many relationship returns a Doctrine_Record instead of Doctrine_CollectionDoctrine 一对多关系返回 Doctrine_Record 而不是 Doctrine_Collection
【发布时间】:2010-10-07 17:44:44
【问题描述】:

我在我的应用程序中遇到了一些问题,当我尝试以 @987654322 访问它时,定义为一对多关系的关系返回一个模型对象(Doctrine_Record 的实例)而不是 Doctrine_Collection @。当然,这会产生如下异常:

Doctrine_Exception:AuditLogProperty 不支持添加

#0 路径\library\Doctrine\Access.php(131): Doctrine_Access->add(Object(AuditLogProperty))

#1 路径\application\models\Article.php(58): Doctrine_Access->offsetSet(NULL, 对象(AuditLogProperty))

#2 路径\library\Doctrine\Record.php(354): 文章->postInsert(Object(Doctrine_Event))

#3 路径\library\Doctrine\Connection\UnitOfWork.php(576): Doctrine_Record->invokeSaveHooks('post', '插入',对象(Doctrine_Event))

#4 路径\library\Doctrine\Connection\UnitOfWork.php(81): Doctrine_Connection_UnitOfWork->insert(Object(Article))

#5 路径\library\Doctrine\Record.php(1718): Doctrine_Connection_UnitOfWork->saveGraph(Object(Article))

#6 路径\application\modules\my-page\controllers\ArticleController.php(26): Doctrine_Record->save()

#7 路径\library\Zend\Controller\Action.php(513): MyPage_ArticleController->createAction()

#8 路径\library\Zend\Controller\Dispatcher\Standard.php(289): Zend_Controller_Action->dispatch('createAction')

#9 路径\library\Zend\Controller\Front.php(946): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), 对象(Zend_Controller_Response_Http))

#10 路径\library\Zend\Application\Bootstrap\Bootstrap.php(77): Zend_Controller_Front->dispatch()

#11 路径\library\Zend\Application.php(358): Zend_Application_Bootstrap_Bootstrap->run()

#12 路径\public\index.php(11): Zend_Application->run()

#13 {主}

这就是我的 yaml 架构的样子(摘录):

AuditLogEntry:
  tableName: audit_log_entries
  actAs:
    Timestampable:
      updated: {disabled: true}
  columns:
    user_id: {type: integer(8), unsigned: true, primary: true}
    id: {type: integer(8), unsigned: true, primary: true, autoincrement: true}
    type: {type: string(255), notnull: true}
    mode: {type: string(16)}
    article_id: {type: integer(8), unsigned: true}
    comment_id: {type: integer(8), unsigned: true}
    question_id: {type: integer(8), unsigned: true}
    answer_id: {type: integer(8), unsigned: true}
    message_id: {type: integer(8), unsigned: true}
  indexes:
#   Must index autoincrementing id-column since it's a compound primary key and 
#   the auto-incrementing column is not the first column and we use InnoDB.
    id: {fields: [id]}
    type: {fields: [type, mode]}
  relations:
    User:
      local: user_id
      foreign: user_id
      foreignAlias: AuditLogs
      type: one
      onDelete: CASCADE
      onUpdate: CASCADE

然后我们有相关的模型:

AuditLogProperty:
  tableName: audit_log_properties
  columns:
    auditlog_id: {type: integer(8), unsigned: true, primary: true}
    prop_id: {type: integer(2), unsigned: true, primary: true, default: 1}
    name: {type: string(255), notnull: true}
    value: {type: string(1024)}
  relations:
    AuditLogEntry:
      local: auditlog_id
      foreign: id
      type: one
      foreignType: many
      foreignAlias: Properties
      onDelete: CASCADE
      onUpdate: CASCADE

现在,如果我们查看生成的类文件,它看起来不错:

/**
 * @property integer $user_id
 * @property integer $id
 * @property string $type
 * @property string $mode
 * @property integer $article_id
 * @property integer $comment_id
 * @property integer $question_id
 * @property integer $answer_id
 * @property integer $message_id
 * @property integer $news_comment_id
 * @property User $User
 * @property Doctrine_Collection $Properties
 * @property Doctrine_Collection $Notifications
 */
abstract class BaseAuditLogEntry extends Doctrine_Record

/**
 * @property integer $auditlog_id
 * @property integer $prop_id
 * @property string $name
 * @property string $value
 * @property AuditLogEntry $AuditLogEntry
 */
abstract class BaseAuditLogProperty extends Doctrine_Record

但是,当我稍后尝试添加属性时,我在问题的开头发布了异常:

$auditLog = new AuditLogEntry();
$prop1 = new AuditLogProperty();
$prop1->name = 'title';
$prop1->value = $this->Content->title;
$prop2 = new AuditLogProperty();
$prop2->name = 'length';
$prop2->value = count($this->Content->plainText);
$auditLog->Properties[] = $prop1;
$auditLog->Properties[] = $prop2;
$auditLog->save();

如果我执行以下操作:

var_dump(get_class($auditLog->Properties));

我知道Properties 的类型是AuditLogProperty,而不是Doctrine_Collection

我使用 1.2.3 版的 Doctrine。

  • 谁能找出问题所在?
  • 我使用复合主键的问题是 Doctrine 不赞成的吗?
  • 有什么解决方法的想法吗?

【问题讨论】:

标签: php database zend-framework doctrine


【解决方案1】:

这不是错误。 :)

这里的问题在于 AuditLogProperty 模型中的 auditlog_id 字段。

  1. 此字段是主键
  2. 此字段也是外键
  3. 条件 1 和 2 不能同时适用。

编辑:这因数据库类型而异,但 Doctrine 不允许(似乎)这样做。

一旦您从 AuditLogProperty 模型的 auditlog_id 字段中删除 'primary: true' 并重新创建数据库,您就会发现问题消失了。

我不知道为什么这是不可能的,但我绝不建议也将外键设为主键(除非它发生在多对多关系的引用表中)。如果您需要 FK 是唯一的,请改用 'unique:true'。

我确实理解您只想拥有一次 prop_id 和 auditlog_id 的组合。据我所知,在 Doctrine 中实现这一点的唯一方法是在模型中使用业务规则。例如,您可以在 PHP 类中实现公共函数 preInsert($event),当出现问题时进行检查并抛出异常(Doctrine 也会这样做)。

【讨论】:

  • 它们可以同时申请,这取决于您插入数据库的顺序。我以这种方式订购它是因为我希望保留以下属性: 1. AuditLog 依赖于现有用户。除非用户存在于数据库中,否则他不会在系统中执行任何操作。 2. AuditLogProperty 依赖于 AuditLog 记录。不应插入不引用 AuditLog 记录的属性。 3. 我希望以有效的方式对 AuditLog 和 AuditLogProperty 进行集群。所以,由于可以在没有 Docrine 的情况下使用此架构,因此这是一个限制
  • 这可能是由与数据库无关的范例引入的限制。据我所知,MySQL 确实支持 PK 字段上的 FK 约束,但很长一段时间以来都不支持。我认为因为 Doctrine 想要与数据库无关,所以它们仍然支持对 PK 字段没有 FK 约束的数据库。
猜你喜欢
  • 1970-01-01
  • 2020-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-26
相关资源
最近更新 更多