Symfony2& FOSRestBundle:将UUID封装在MySQL的BINARY(16)字段中 [英] Symfony2 & FOSRestBundle: Getting UUID packed in a BINARY(16) field from MySQL
问题描述
我已经使用Symfony2 + FOSRestBundle + JMSSerializer开发了一个REST API。因为我需要从两个来源更新一些表,我以为使用UUID作为一个实体的主键。
我做了一个教义:mapping:import在我的Symfony项目。一切都正确我结束了以下实体(只是为了简单地暴露了关键字段和生成的getter):
<?php
命名空间Stardigita\TgaAPIBundle\Entity;
使用Doctrine\ORM\Mapping作为ORM;
/ **
* TgaBookings
*
* @ ORM\Table(name =tga_bookings,indexes = {[...]})
* @ ORM\Entity
* /
class TgaBookings
{
/ **
* @var string
*
* @ ORM\Column(name =book_cd_booking_UUID,type =blob,length = 16,nullable = false)
* @ ORM\Id
* @ ORM\GeneratedValue(strategy = IDENTITY)
* /
private $ bookCdBookingUuid;
/ **
*获取bookCdBookingUuid
*
* @return string
* /
public function getBookCdBookingUuid()
{
return $ this-> bookCdBookingUuid;
}
...
没有生成setter。我仍然可以自己做,我会,因为我需要事先知道密钥。
该字段的数据作为BINARY正确存储在表中16)。当我恢复调用REST GET方法的数据时,我得到这个:
[
{
book_cd_booking_uuid:资源ID#1244,
book_cd_booking:8,
....
我的问题是:如何从字段中获取实际数据?
我想在字段getter中必须做一些事情,但是我尝试了一些解决方案,没有任何成功。
谢谢。
更新:
我设法获取实际的数据,修改了getBookCdBookingUuid方法:
/ **
*获取bookCdBookingUuid
*
* @return string
* /
public function getBookCdBookingUuid()
{
return bin2hex($ this-> bookCdBookingUuid);
}
并在属性注释中将类型更改为guid:
/ **
* @var string
*
* @ ORM\Column(name = book_cd_booking_UUID,type =guid,length = 16,nullable = false)
* @ ORM\Id
* @ ORM\GeneratedValue(strategy =IDENTITY)
* /
private $ bookCdBookingUuid;
我在日志中正确表示十六进制UUID,然后在控制器中返回结果:
[2014-11-03 19:52:07] app.ERROR:1046684e5f6711e4a09f00089bce936a [] []
但仍然收到与UTF无效字符相关的异常:
code> request.CRITICAL:未捕获PHP异常RuntimeException:您的数据无法编码,因为它包含无效的UTF8字符。在/var/www/tga_api/vendor/jms/serializer/src/JMS/Serializer/JsonSerializationVisitor.php第36行{exception:[object](RuntimeException:您的数据无法编码,因为它包含无效的UTF8字符。在/var/www/tga_api/vendor/jms/serializer/src/JMS/Serializer/JsonSerializationVisitor.php:36)} []
此外,我没有收到服务的回复。返回500错误。
请,我需要解决这个问题。任何想法都是受欢迎的。
谢谢。
GeneratedValue < h3>
我注意到您正在使用UUID属性的注释 @ ORM\GeneratedValue(strategy =IDENTITY)
。 IDENTITY
表示数据库应该/将使用自动增量,在使用UUID时不应该这样做。请将其更改为 @ ORM\GeneratedValue(strategy =NONE)
或完全删除。
转换
UUID的字符串形式(如 01234567-89ab-cdef-0123-456789abcdef
)应转换为二进制文件保存在数据库中,并从数据库中提取时转换。
最简单的方法是引入一个自定义类型。有关示例,请参见此处
错误
Doctrine(甚至master / 2.5)在关联中使用UUID有一些问题。我试图在 PR#1178 中解决这些问题。
如果您需要关联的UUID,并且无法等到固定,那么使用正则整数,并且UUID是单独的列。
I am facing a weird problem relating to UUIDs.
I have developed a REST API using Symfony2+FOSRestBundle+JMSSerializer. As I need to update some tables from two sources I thought of using UUID as primary key for one entity.
I did a doctrine:mapping:import to generate entities in my Symfony project. Everything correct. I ended up with the following entity (only exposing the key field and generated getter for simplicity):
<?php
namespace Stardigita\TgaAPIBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* TgaBookings
*
* @ORM\Table(name="tga_bookings", indexes={[...]})
* @ORM\Entity
*/
class TgaBookings
{
/**
* @var string
*
* @ORM\Column(name="book_cd_booking_UUID", type="blob", length=16, nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $bookCdBookingUuid;
/**
* Get bookCdBookingUuid
*
* @return string
*/
public function getBookCdBookingUuid()
{
return $this->bookCdBookingUuid;
}
...
No setter was generated. I can still do it myself and I will, as I will need to know the key beforehand.
The data for this field is correctly stored in the table as a BINARY(16). When I recover the data calling the REST GET method, I get this:
[
{
"book_cd_booking_uuid": "Resource id #1244",
"book_cd_booking": 8,
....
My question is: how can I get the actual data from the field?
I suppose something has to be done in the field getter, but I tried some solutions without any success.
Thanks.
UPDATE: I've managed to get the actual data logged, modifying the getBookCdBookingUuid method this way:
/**
* Get bookCdBookingUuid
*
* @return string
*/
public function getBookCdBookingUuid()
{
return bin2hex($this->bookCdBookingUuid);
}
and changed the type to "guid" in the property annotation:
/**
* @var string
*
* @ORM\Column(name="book_cd_booking_UUID", type="guid", length=16, nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $bookCdBookingUuid;
I have represented the hex UUID correctly in the log before returning the results in the controller:
[2014-11-03 19:52:07] app.ERROR: 1046684e5f6711e4a09f00089bce936a [] []
But still getting an exception relating UTF invalid characters:
request.CRITICAL: Uncaught PHP Exception RuntimeException: "Your data could not be encoded because it contains invalid UTF8 characters." at /var/www/tga_api/vendor/jms/serializer/src/JMS/Serializer/JsonSerializationVisitor.php line 36 {"exception":"[object] (RuntimeException: Your data could not be encoded because it contains invalid UTF8 characters. at /var/www/tga_api/vendor/jms/serializer/src/JMS/Serializer/JsonSerializationVisitor.php:36)"} []
Also I got no response from the service. A 500 error is returned.
Please, I need to solve this issue. Any ideas are welcome.
Thanks.
GeneratedValue
I notice you're using the annotation @ORM\GeneratedValue(strategy="IDENTITY")
for the UUID property. IDENTITY
means the database should/will use auto-increments, which shouldn't be done when using UUIDs. Please change it to @ORM\GeneratedValue(strategy="NONE")
or remove it completely.
Conversion
The string form of a UUID (like 01234567-89ab-cdef-0123-456789abcdef
) should be converted to binary when it's persisted in the database, and converted back when fetched from the database.
The easiest way to do this is to introduce a custom type. See here for an example.
Bugs
Doctrine (even master/2.5) has some issues with using UUIDs in associations. I'm attempting to fix these issues in PR #1178.
If you need UUIDs in associations and can't wait till it's fixed, then use regular integer ids and have the UUID is a separate column.
这篇关于Symfony2& FOSRestBundle:将UUID封装在MySQL的BINARY(16)字段中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!