alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Hibernate example source code file (example_parentchild.po)

This example Hibernate source code file (example_parentchild.po) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Hibernate tags/keywords

cdata, cdata, child, child, hibernate, hibernate, in, parent, tag, tag, the, this, we, you

The Hibernate example_parentchild.po source code

# translation of Collection_Mapping.po to
# Xi Huang <xhuang@redhat.com>, 2006.
# Xi HUANG <xhuang@redhat.com>, 2007.
msgid ""
msgstr ""
"Project-Id-Version: Collection_Mapping\n"
"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
"POT-Creation-Date: 2010-02-10T07:25:35\n"
"PO-Revision-Date: 2010-03-16 10:04+1000\n"
"Last-Translator: Xi HUANG <xhuang@redhat.com>\n"
"Language-Team:  <en@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"

#. Tag: title
#, no-c-format
msgid "Example: Parent/Child"
msgstr "示例:父子关系(Parent/Child)"

#. Tag: para
#, no-c-format
msgid "One of the first things that new users want to do with Hibernate is to model a parent/child type relationship. There are two different approaches to this. The most convenient approach, especially for new users, is to model both <literal>Parent and Child as entity classes with a <one-to-many> association from Parent to Child. The alternative approach is to declare the Child as a <composite-element>. The default semantics of a one-to-many association in Hibernate are much less close to the usual semantics of a parent/child relationship than those of a composite element mapping. We will explain how to use a bidirectional one-to-many association with cascades to model a parent/child relationship efficiently and elegantly."
msgstr "刚刚接触 Hibernate 的人大多是从父子关系(parent / child type relationship)的建模入手的。父子关系的建模有两种方法。由于种种原因,最方便的方法是把 <literal>Parent 和 Child 都建模成实体类,并创建一个从 Parent 指向 Child 的 <one-to-many> 关联,对新手来说尤其如此。还有一种方法,就是将 Child 声明为一个 <composite-element>(组合元素)。 事实上在 Hibernate 中 one to many 关联的默认语义远没有 composite element 贴近 parent / child 关系的通常语义。下面我们会阐述如何使用带有级联的双向一对多关联(idirectional one to many association with cascades)去建立有效、优美的 parent / child 关系。"

#. Tag: title
#, no-c-format
msgid "A note about collections"
msgstr "关于 collections 需要注意的一点"

#. Tag: para
#, no-c-format
msgid "Hibernate collections are considered to be a logical part of their owning entity and not of the contained entities. Be aware that this is a critical distinction that has the following consequences:"
msgstr "Hibernate collections 被当作其所属实体而不是其包含实体的一个逻辑部分。这非常重要,它主要体现为以下几点:"

#. Tag: para
#, no-c-format
msgid "When you remove/add an object from/to a collection, the version number of the collection owner is incremented."
msgstr "当删除或增加 collection 中对象的时候,collection 所属者的版本值会递增。 "

#. Tag: para
#, no-c-format
msgid "If an object that was removed from a collection is an instance of a value type (e.g. a composite element), that object will cease to be persistent and its state will be completely removed from the database. Likewise, adding a value type instance to the collection will cause its state to be immediately persistent."
msgstr "如果一个从 collection 中移除的对象是一个值类型(value type)的实例,比如 composite element,那么这个对象的持久化状态将会终止,其在数据库中对应的记录会被删除。同样的,向 collection 增加一个 value type 的实例将会使之立即被持久化。 "

#. Tag: para
#, no-c-format
msgid "Conversely, if an entity is removed from a collection (a one-to-many or many-to-many association), it will not be deleted by default. This behavior is completely consistent; a change to the internal state of another entity should not cause the associated entity to vanish. Likewise, adding an entity to a collection does not cause that entity to become persistent, by default."
msgstr "另一方面,如果从一对多或多对多关联的 collection 中移除一个实体,在缺省情况下这个对象并不会被删除。这个行为是完全合乎逻辑的--改变一个实体的内部状态不应该使与它关联的实体消失掉。同样的,向 collection 增加一个实体不会使之被持久化。 "

#. Tag: para
#, no-c-format
msgid "Adding an entity to a collection, by default, merely creates a link between the two entities. Removing the entity will remove the link. This is appropriate for all sorts of cases. However, it is not appropriate in the case of a parent/child relationship. In this case, the life of the child is bound to the life cycle of the parent."
msgstr "实际上,向 Collection 增加一个实体的缺省动作只是在两个实体之间创建一个连接而已,同样移除的时候也只是删除连接。这种处理对于所有的情况都是合适的。对于父子关系则是完全不适合的,在这种关系下,子对象的生存绑定于父对象的生存周期。 "

#. Tag: title
#, no-c-format
msgid "Bidirectional one-to-many"
msgstr "双向的一对多关系(Bidirectional one-to-many)"

#. Tag: para
#, no-c-format
msgid "Suppose we start with a simple <literal><one-to-many> association from Parent to Child."
msgstr "假设我们要实现一个简单的从 Parent 到 Child 的 <one-to-many> 关联。"

#. Tag: para
#, no-c-format
msgid "If we were to execute the following code:"
msgstr "如果我们运行下面的代码:"

#. Tag: para
#, no-c-format
msgid "Hibernate would issue two SQL statements:"
msgstr "Hibernate 会产生两条 SQL 语句:"

#. Tag: para
#, no-c-format
msgid "an <literal>INSERT to create the record for c"
msgstr "一条 <literal>INSERT 语句,为 c 创建一条记录"

#. Tag: para
#, no-c-format
msgid "an <literal>UPDATE to create the link from p to c"
msgstr "一条 <literal>UPDATE 语句,创建从 pc 的连接"

#. Tag: para
#, no-c-format
msgid "This is not only inefficient, but also violates any <literal>NOT NULL constraint on the parent_id column. You can fix the nullability constraint violation by specifying not-null=\"true\" in the collection mapping:"
msgstr "这样做不仅效率低,而且违反了 <literal>parent_id 列 parent_id 非空的限制。我们可以通过在集合类映射上指定 not-null=\"true\" 来解决违反非空约束的问题:"

#. Tag: para
#, no-c-format
msgid "However, this is not the recommended solution."
msgstr "然而,这并非是推荐的解决方法。"

#. Tag: para
#, no-c-format
msgid "The underlying cause of this behavior is that the link (the foreign key <literal>parent_id) from p to c is not considered part of the state of the Child object and is therefore not created in the INSERT. The solution is to make the link part of the Child mapping."
msgstr "这种现象的根本原因是从 <literal>p 到 c 的连接(外键 parent_id)没有被当作 Child 对象状态的一部分,因而没有在 INSERT 语句中被创建。因此解决的办法就是把这个连接添加到 Child 的映射中。"

#. Tag: para
#, no-c-format
msgid "You also need to add the <literal>parent property to the Child class."
msgstr "你还需要为类 <literal>Child 添加 parent 属性。"

#. Tag: para
#, no-c-format
msgid "Now that the <literal>Child entity is managing the state of the link, we tell the collection not to update the link. We use the inverse attribute to do this:"
msgstr "现在实体 <literal>Child 在管理连接的状态,为了使 collection 不更新连接,我们使用 inverse 属性:"

#. Tag: para
#, no-c-format
msgid "The following code would be used to add a new <literal>Child:"
msgstr "下面的代码是用来添加一个新的 <literal>Child:"

#. Tag: para
#, no-c-format
msgid "Only one SQL <literal>INSERT would now be issued."
msgstr "现在,只会有一条 <literal>INSERT 语句被执行。"

#. Tag: para
#, no-c-format
msgid "You could also create an <literal>addChild() method of Parent."
msgstr "为了让事情变得井井有条,可以为 <literal>Parent 加一个 addChild() 方法。"

#. Tag: para
#, no-c-format
msgid "The code to add a <literal>Child looks like this:"
msgstr "现在,添加 <literal>Child 的代码就是这样:"

#. Tag: title
#, no-c-format
msgid "Cascading life cycle"
msgstr "级联生命周期(Cascading lifecycle) "

#. Tag: para
#, no-c-format
msgid "You can address the frustrations of the explicit call to <literal>save() by using cascades."
msgstr "需要显式调用 <literal>save() 仍然很麻烦,我们可以用级联来解决这个问题。 "

#. Tag: para
#, no-c-format
msgid "This simplifies the code above to:"
msgstr "这样上面的代码可以简化为: "

#. Tag: para
#, no-c-format
msgid "Similarly, we do not need to iterate over the children when saving or deleting a <literal>Parent. The following removes p and all its children from the database."
msgstr "同样的,保存或删除 <literal>Parent 对象的时候并不需要遍历其子对象。下面的代码会删除对象 p 及其所有子对象对应的数据库记录。 "

#. Tag: para
#, no-c-format
msgid "However, the following code:"
msgstr "然而,这段代码:"

#. Tag: para
#, no-c-format
msgid "will not remove <literal>c from the database. In this case, it will only remove the link to p and cause a NOT NULL constraint violation. You need to explicitly delete() the Child."
msgstr "不会从数据库删除<literal>c;它只会删除与 p 之间的连接(并且会导致违反 NOT NULL 约束,在这个例子中)。你需要显式调用 delete() 来删除 Child。 "

#. Tag: para
#, no-c-format
msgid "In our case, a <literal>Child cannot exist without its parent. So if we remove a Child from the collection, we do want it to be deleted. To do this, we must use cascade=\"all-delete-orphan\"."
msgstr "在我们的例子中,如果没有父对象,子对象就不应该存在,如果将子对象从 collection 中移除,实际上我们是想删除它。要实现这种要求,就必须使用 <literal>cascade=\"all-delete-orphan\"。 "

#. Tag: para
#, no-c-format
msgid "Even though the collection mapping specifies <literal>inverse=\"true\", cascades are still processed by iterating the collection elements. If you need an object be saved, deleted or updated by cascade, you must add it to the collection. It is not enough to simply call setParent()."
msgstr "注意:即使在 collection 一方的映射中指定 <literal>inverse=\"true\",级联仍然是通过遍历 collection 中的元素来处理的。如果你想要通过级联进行子对象的插入、删除、更新操作,就必须把它加到 collection 中,只调用 setParent() 是不够的。 "

#. Tag: title
#, no-c-format
msgid "Cascades and <literal>unsaved-value"
msgstr "级联与未保存值(<literal>unsaved-value)"

#. Tag: para
#, no-c-format
msgid "Suppose we loaded up a <literal>Parent in one Session, made some changes in a UI action and wanted to persist these changes in a new session by calling update(). The Parent will contain a collection of children and, since the cascading update is enabled, Hibernate needs to know which children are newly instantiated and which represent existing rows in the database. We will also assume that both Parent and Child have generated identifier properties of type Long. Hibernate will use the identifier and version/timestamp property value to determine which of the children are new. (See .) In Hibernate3, it is no longer necessary to specify an unsaved-value explicitly."
msgstr "假设我们从 <literal>Session 中装入了一个 Parent 对象,用户界面对其进行了修改,然后希望在一个新的 Session 里面调用 update() 来保存这些修改。对象 Parent 包含了子对象的集合,由于打开了级联更新,Hibernate 需要知道哪些 Child 对象是新实例化的,哪些代表数据库中已经存在的记录。我们假设 ParentChild 对象的标识属性都是自动生成的,类型为 Long。Hibernate 会使用标识属性的值,和 version 或 timestamp 属性,来判断哪些子对象是新的。(参见 在 Hibernate3 中,显式指定 unsaved-value 不再是必须的了。 "

#. Tag: para
#, no-c-format
msgid "The following code will update <literal>parent and child and insert newChild:"
msgstr "下面的代码会更新 <literal>parent 和 child 对象,并且插入 newChild 对象。 "

#. Tag: para
#, no-c-format
msgid "This may be suitable for the case of a generated identifier, but what about assigned identifiers and composite identifiers? This is more difficult, since Hibernate cannot use the identifier property to distinguish between a newly instantiated object, with an identifier assigned by the user, and an object loaded in a previous session. In this case, Hibernate will either use the timestamp or version property, or will actually query the second-level cache or, worst case, the database, to see if the row exists."
msgstr "这对于自动生成标识的情况是非常好的,但是自分配的标识和复合标识怎么办呢?这是有点麻烦,因为 Hibernate 没有办法区分新实例化的对象(标识被用户指定了)和前一个 Session 装入的对象。在这种情况下,Hibernate 会使用 timestamp 或 version 属性,或者查询第二级缓存,或者最坏的情况,查询数据库,来确认是否此行存在。 "

#. Tag: title
#, no-c-format
msgid "Conclusion"
msgstr "结论"

#. Tag: para
#, no-c-format
msgid "The sections we have just covered can be a bit confusing. However, in practice, it all works out nicely. Most Hibernate applications use the parent/child pattern in many places."
msgstr "这里有不少东西需要融会贯通,可能会让新手感到迷惑。但是在实践中它们都工作地非常好。大部分 Hibernate 应用程序都会经常用到父子对象模式。 "

#. Tag: para
#, no-c-format
msgid "We mentioned an alternative in the first paragraph. None of the above issues exist in the case of <literal><composite-element> mappings, which have exactly the semantics of a parent/child relationship. Unfortunately, there are two big limitations with composite element classes: composite elements cannot own collections and they should not be the child of any entity other than the unique parent."
msgstr "在第一段中我们曾经提到另一个方案。上面的这些问题都不会出现在 <literal><composite-element> 映射中,它准确地表达了父子关系的语义。很不幸复合元素还有两个重大限制:复合元素不能拥有 collections,并且,除了用于惟一的父对象外,它们不能再作为其它任何实体的子对象。 "

#~ msgid ""
#~ "<![CDATA["
#~ msgstr ""
#~ "<![CDATA["
#~ msgid ""
#~ "<![CDATA[Parent p = .....;\n"
#~ "Child c = new Child();\n"
#~ "p.getChildren().add(c);\n"
#~ "session.save(c);\n"
#~ "session.flush();]]>"
#~ msgstr ""
#~ "<![CDATA[Parent p = .....;\n"
#~ "Child c = new Child();\n"
#~ "p.getChildren().add(c);\n"
#~ "session.save(c);\n"
#~ "session.flush();]]>"
#~ msgid ""
#~ "<![CDATA["
#~ msgstr ""
#~ "<![CDATA["
#~ msgid ""
#~ "<![CDATA["
#~ msgstr ""
#~ "<![CDATA["
#~ msgid ""
#~ "<![CDATA["
#~ msgstr ""
#~ "<![CDATA["
#~ msgid ""
#~ "<![CDATA[Parent p = (Parent) session.load(Parent.class, pid);\n"
#~ "Child c = new Child();\n"
#~ "c.setParent(p);\n"
#~ "p.getChildren().add(c);\n"
#~ "session.save(c);\n"
#~ "session.flush();]]>"
#~ msgstr ""
#~ "<![CDATA[Parent p = (Parent) session.load(Parent.class, pid);\n"
#~ "Child c = new Child();\n"
#~ "c.setParent(p);\n"
#~ "p.getChildren().add(c);\n"
#~ "session.save(c);\n"
#~ "session.flush();]]>"
#~ msgid ""
#~ "<![CDATA[public void addChild(Child c) {\n"
#~ "    c.setParent(this);\n"
#~ "    children.add(c);\n"
#~ "}]]>"
#~ msgstr ""
#~ "<![CDATA[public void addChild(Child c) {\n"
#~ "    c.setParent(this);\n"
#~ "    children.add(c);\n"
#~ "}]]>"
#~ msgid ""
#~ "<![CDATA[Parent p = (Parent) session.load(Parent.class, pid);\n"
#~ "Child c = new Child();\n"
#~ "p.addChild(c);\n"
#~ "session.save(c);\n"
#~ "session.flush();]]>"
#~ msgstr ""
#~ "<![CDATA[Parent p = (Parent) session.load(Parent.class, pid);\n"
#~ "Child c = new Child();\n"
#~ "p.addChild(c);\n"
#~ "session.save(c);\n"
#~ "session.flush();]]>"
#~ msgid ""
#~ "<![CDATA["
#~ msgstr ""
#~ "<![CDATA["
#~ msgid ""
#~ "<![CDATA[Parent p = (Parent) session.load(Parent.class, pid);\n"
#~ "Child c = new Child();\n"
#~ "p.addChild(c);\n"
#~ "session.flush();]]>"
#~ msgstr ""
#~ "<![CDATA[Parent p = (Parent) session.load(Parent.class, pid);\n"
#~ "Child c = new Child();\n"
#~ "p.addChild(c);\n"
#~ "session.flush();]]>"
#~ msgid ""
#~ "<![CDATA[Parent p = (Parent) session.load(Parent.class, pid);\n"
#~ "session.delete(p);\n"
#~ "session.flush();]]>"
#~ msgstr ""
#~ "<![CDATA[Parent p = (Parent) session.load(Parent.class, pid);\n"
#~ "session.delete(p);\n"
#~ "session.flush();]]>"
#~ msgid ""
#~ "<![CDATA[Parent p = (Parent) session.load(Parent.class, pid);\n"
#~ "Child c = (Child) p.getChildren().iterator().next();\n"
#~ "p.getChildren().remove(c);\n"
#~ "c.setParent(null);\n"
#~ "session.flush();]]>"
#~ msgstr ""
#~ "<![CDATA[Parent p = (Parent) session.load(Parent.class, pid);\n"
#~ "Child c = (Child) p.getChildren().iterator().next();\n"
#~ "p.getChildren().remove(c);\n"
#~ "c.setParent(null);\n"
#~ "session.flush();]]>"
#~ msgid ""
#~ "<![CDATA[Parent p = (Parent) session.load(Parent.class, pid);\n"
#~ "Child c = (Child) p.getChildren().iterator().next();\n"
#~ "p.getChildren().remove(c);\n"
#~ "session.delete(c);\n"
#~ "session.flush();]]>"
#~ msgstr ""
#~ "<![CDATA[Parent p = (Parent) session.load(Parent.class, pid);\n"
#~ "Child c = (Child) p.getChildren().iterator().next();\n"
#~ "p.getChildren().remove(c);\n"
#~ "session.delete(c);\n"
#~ "session.flush();]]>"
#~ msgid ""
#~ "<![CDATA["
#~ msgstr ""
#~ "<![CDATA["
#~ msgid ""
#~ "<![CDATA[//parent and child were both loaded in a previous session\n"
#~ "parent.addChild(child);\n"
#~ "Child newChild = new Child();\n"
#~ "parent.addChild(newChild);\n"
#~ "session.update(parent);\n"
#~ "session.flush();]]>"
#~ msgstr ""
#~ "<![CDATA[//parent and child were both loaded in a previous session\n"
#~ "parent.addChild(child);\n"
#~ "Child newChild = new Child();\n"
#~ "parent.addChild(newChild);\n"
#~ "session.update(parent);\n"
#~ "session.flush();]]>"

Other Hibernate examples (source code examples)

Here is a short list of links related to this Hibernate example_parentchild.po source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.