教义中的两个产生的价值观 [英] Two Generated Values in Doctrine

查看:104
本文介绍了教义中的两个产生的价值观的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的教义实体中实现一个人性化的ID。我想保留DB-ID工作,并添加像PRE12-00005(使用前缀和年份,并从新的一年开始为0)。我试图添加一个自定义ID生成器,但似乎原则不能与一个实体中的两个生成的值一起使用。

  / ** 
* @var integer
* @ ORM\Column(name =id,type =integer)
* @ ORM\Id
* @ ORM\GeneratedValue(strategy =IDENTITY)
* /
protected $ id;

/ **
* @var string
* @ ORM\Column(name =name,type =string,length = 25,unique = true)
* @ ORM\GeneratedValue(strategy =CUSTOM)
* @ ORM\CustomIdGenerator(class =NameGenerator)
* /
protected $ name;

Doctrine总是尝试将我的生成器中的返回值保存到id中 - 名称。是否有另一种方法来实现?

解决方案

从我所知道的GeneratedValue策略是为主键保留的,这意味着你可以每个实体只能使用一次。



根据您的需要,您可以选择一些选项:




  • 您可以随时使用 prePersist生命周期事件,在您保留第一次之前设置您喜欢的任何值。


  • 如果您依赖于id从它生成另一个唯一的ID,你可以实现一个postPersist事件,在那里设置你的名字,并确保你刷新两次(第一次生成主键,第二次保存名称)。


  • 如果您的数据库中的名称为空,一段时间后,可以执行一个postLoad事件,如果它是空的,则填写该名称。这样你的应用程序总是看到这个名字(因为它是从数据库加载的,或者是由postLoad事件填充的),当你在初始保存后首次添加或编辑信息时,你的名字也将被保存。


  • 可以不保存名称,并由某个cronjob / deamon / queue生成,因此您的应用程序不必处理它。你唯一需要做的就是确保一个丢失的名字不会弄乱某些东西。


  • 也许这可能是生成一个不是取决于主键,因此可以由全局事件处理程序生成。你当然有这样的缺点,因为他是全局的,因为它是持续的每一个对象都被调用,不管它是否是正确的实体。


  • 最后但并非最不重要的是,可以回到存储过程/触发器,让数据库处理这个。这样你就不必在应用程序中弄乱这个。但请注意,路上可能存在陷阱(像开发人员忘记这一点,因为它不在代码中,而是在数据库中)。




可能还有其他方法。我想说的是:不要对非主键属性使用generatedValue!


i would like to implement a human-readable ID in my Doctrine-Entity. I want to keep the DB-ID for working and adding something like "PRE12-00005" (with Prefix and Year, and start at 0 every new year). I tried to add a Custom-ID-Generator, but it seems that Doctrine can't work with two generated Values in one Entity.

/**
 * @var integer
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
protected $id;

/**
 * @var string
 * @ORM\Column(name="name", type="string", length=25, unique=true)
 * @ORM\GeneratedValue(strategy="CUSTOM")
 * @ORM\CustomIdGenerator(class="NameGenerator")
 */
protected $name;

Doctrine always try to save the return value from my generator into the "id"-Field and null into "name". Is there another way to implement it?

解决方案

From what I know the GeneratedValue strategy is reserved for the primary key, meaning you can only use it once per Entity.

Depending on your needs you have a few options though:

  • You can always have a prePersist lifecycle event, setting any value you like for the name before you persist it the first time.

  • If you depend on the id to generate another unique id from it, you could implement a postPersist event, set your name there and make sure you flush twice (The first time to generate the primary key, the second time to save the name).

  • If it's ok for you that the name is empty in the database for some time, it could be ok to implement a postLoad event, which fills the name if it's empty. This way your application always sees the name (because it's either loaded from the database or filled by the postLoad event) and when you add or edit information the first time after the initial save, your name will also be saved

  • It could be ok to not save the name and have it generated by some cronjob/deamon/queue so your application does not have to deal with it. The only thing you would need to do is make sure a missing name does not screw up something.

  • Maybe it might be ok to generate a key which does not depend on the primary key and thus can be generated by an global event handler. You of course have the drawback that such an event handler, because he is global, gets called for every object you persist, no matter if it's the correct entity.

  • Last, but not least, it might be ok to fallback to Stored Procedures/Triggers to let the database handle this. This way you don't have to mess with this inside your application. But beware, there might be pitfalls on the way (like a developer forgetting about this because it's not in the code but in the database!).

There may be other ways. What I was trying to say is: Don't use generatedValue for non-primary key properties!

这篇关于教义中的两个产生的价值观的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆