Doctrine一对多关系返回Doctrine_Record而不是Doctrine_Collection

时间:2010-09-30 11:14:14

标签: php database zend-framework doctrine

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

  

Doctrine_Exception:AuditLogProperty

不支持Add      

#0 路径 \ library \ Doctrine \ Access.php(131):   Doctrine_Access->添加(对象(AuditLogProperty))

     

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

     

#2 路径 \ library \ Doctrine \ Record.php(354):   物品─> postInsert(对象(Doctrine_Event))

     

#3 路径 \ library \ Doctrine \ Connection \ UnitOfWork.php(576):   Doctrine_Record-> invokeSaveHooks( '后',   'insert',Object(Doctrine_Event))

     

#4 路径 \ library \ Doctrine \ Connection \ UnitOfWork.php(81):   Doctrine_Connection_UnitOfWork->插入(对象(第))

     

#5 路径 \ library \ Doctrine \ Record.php(1718):   Doctrine_Connection_UnitOfWork-> saveGraph(对象(第))

     

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

     

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

     

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

     

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

     

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

     

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

     

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

     

#13 {main}

这就是我的yaml-schema看起来像(摘录):

$model->RelatedComponent[] = $child1

然后我们有相关的模型:

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的1.2.3版本。

  • 有人能发现错误吗?
  • 问题是我使用复合主键的方式是Doctrine不赞同的吗?
  • 关于如何解决它的任何想法?

1 个答案:

答案 0 :(得分:1)

这不是错误。 :)

此处的问题在于AuditLogProperty模型中的auditlog_id字段。

  1. 此字段是主键
  2. 此字段也是外键
  3. 条件1和2不能同时适用。
  4. 编辑:这根据数据库类型而有所不同,但是Doctrine并没有(似乎)允许它。

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

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

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