使用 FlexJSON 反序列化多对一关系



我正在为我的Web应用程序(使用Spring)添加RESTful支持,以便我可以执行以下操作的CRUD操作:阅读有关参与者的信息(JSONSerialize):

$ curl -i -H "Accept: application/json" http://localhost:8080/dancingwithstars/participant/1
{
    "birthDate": "2013-01-23",
    "code": "JS0001",
    "firstName": "Julia",
    "mainFunction": {
        "code": "AA"
        "name": "Principal Dancer"
    },
    "gender": "F",
    "height": 160.00,
    "id": 1,
    "lastName": "Smith",
    "version": 1,
    "weight": 55.00
}

或者创建一个新的参与者(JSONDeserialize)

$ curl -i -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{"birthDate":"2013-01-15","code":"AT0001","firstName":"Angela","mainFunction":{"code": "AB", "name":"Choreografer"},"gender":"F","height":189.00,"lastName":"Wright","version":0,"weight":76.00}' http://localhost:8080/dancingwithstars/participants

但问题是,我不需要知道mainFunction对象的所有字段来创建参与者,我只需要知道唯一的代码。对于序列化,我可以使用:

return new JSONSerializer().include("mainFunction.code").exclude("mainFunction.*").exclude("*.class").transform(new DateTransformer("yyyy-MM-dd"), Date.class).prettyPrint(true).serialize(this);

我得到以下json:

{
    "birthDate": "2013-01-23",
    "code": "JS0001",
    "firstName": "Julia",
    "mainFunction": {
        "code": "AA"
    },
    "gender": "F",
    "height": 160.00,
    "id": 1,
    "lastName": "Smith",
    "version": 1,
    "weight": 55.00
}

对于反序列化我不知道。这个要求似乎很常见,所以我想在论坛上问一下。有什么想法吗?

总而言之,有一个父对象引用(多对一)子对象。如果我向父母提供孩子的所有信息,一切正常。但是等一下,用孩子的身份证应该足以保护父母。我尝试仅使用孩子的ID保存父级,然后出现以下异常:

org.hibernate.TransientPropertyValueException:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例

有什么想法吗?

奥古斯丁

2013 年 1 月 27 日更新:问题似乎来自休眠。假设我们有产品和类别。关系是产品具有对类别的引用(多对一关系)。给定以前保存在数据库中的类别。您不能创建产品,而只需提供类别的 ID 即可创建产品。即使Hibernate不会查看版本来创建产品,您也将需要该版本。见下文:

/*
 * Create one category before the product
 */
Category cat1 = new Category();
cat1.setCode("KIT");
cat1.setName("Kitchen products");
session.save(cat1);
session.flush();
session.clear();
Category cat1db = (Category) session.get(Category.class, cat1.getCode());
logger.info(cat1.toString());
assertNotNull(cat1db.getVersion());
/*
 * Create the product and assign it a category
 */
Product p1 = new Product();
p1.setName("Kettle");
p1.setPrice(4D);
Category c1 = new Category();
c1.setCode("KIT");
//c1.setVersion(new Integer(666));
p1.setCategory(c1);
session.save(p1);
session.flush();
session.clear();
Product p1db = (Product) session.get(Product.class, p1.getId());
logger.info(p1.toString());
assertNotNull(p1db.getId());

那将失败。但是,如果您取消注释类别的版本,则将创建产品。此外,Hibernate将对数据库进行额外的查询,要求该类别。

这里有两个问题:

  1. 为什么Hibernate需要字段版本,即使它最终看起来不是它?
  2. 为什么Hibernate会做一个额外的查询来询问类别?

你的想法?

当你处理来自JSON或外部表示的对象时,你总是从Hibernate的角度来看处理分离的对象。

我已经有一段时间没有做任何严肃的休眠了,但是如果您正在创建一个 Hibernate 不知道的对象,您必须通过将对象与会话重新附加来告诉它。 然后,它将从数据库中提取所需的信息以将其与会话相关联,包括任何版本控制信息。 这被称为分离的对象,因为它是在 Hibernate 会话之外创建的,Hibernate 不知道这个对象是新对象还是存在于数据库中的对象。 您可以使用session.merge(someObject)重新附加对象。 顺便说一句,您只需要重新附加父级。 为了更好的解释:

在休眠中重新附加分离的对象的正确方法是什么?

版本信息用于乐观锁定。 因此,在多客户端环境中,两个请求可能会修改数据库中的同一对象,作为程序员,您的工作是对这些修改进行排序并确保其中一个不会覆盖另一个。 乐观锁定是实现此目的的一种方法,当有人修改对象时,对象被赋予版本,版本递增。 但是,在保存新版本之前,您必须检查并确保提供给数据库的对象与存储在数据库中的对象版本相同。 这样可以确保您要保存的模组是在数据库中存储的最新版本上完成的。 这意味着您不能使用该对象的旧版本覆盖该对象。 如果没有该版本信息,Hibernate将无法执行乐观锁定。

相关内容

  • 没有找到相关文章

最新更新