|
Hibernate example source code file (session_api.pot)
This example Hibernate source code file (session_api.pot) 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.
The Hibernate session_api.pot source code
# SOME DESCRIPTIVE TITLE.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
"POT-Creation-Date: 2010-07-21 05:43+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <kde-i18n-doc@kde.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: application/x-xml2pot; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#. Tag: title
#: session_api.xml:31
#, no-c-format
msgid "Working with objects"
msgstr ""
#. Tag: para
#: session_api.xml:33
#, no-c-format
msgid "Hibernate is a full object/relational mapping solution that not only shields the developer from the details of the underlying database management system, but also offers <emphasis>state management of objects. This is, contrary to the management of SQL statements in common JDBC/SQL persistence layers, a natural object-oriented view of persistence in Java applications."
msgstr ""
#. Tag: para
#: session_api.xml:40
#, no-c-format
msgid "In other words, Hibernate application developers should always think about the <emphasis>state of their objects, and not necessarily about the execution of SQL statements. This part is taken care of by Hibernate and is only relevant for the application developer when tuning the performance of the system."
msgstr ""
#. Tag: title
#: session_api.xml:47
#, no-c-format
msgid "Hibernate object states"
msgstr ""
#. Tag: para
#: session_api.xml:49
#, no-c-format
msgid "Hibernate defines and supports the following object states:"
msgstr ""
#. Tag: para
#: session_api.xml:53
#, no-c-format
msgid "<emphasis>Transient - an object is transient if it has just been instantiated using the new operator, and it is not associated with a Hibernate Session. It has no persistent representation in the database and no identifier value has been assigned. Transient instances will be destroyed by the garbage collector if the application does not hold a reference anymore. Use the Hibernate Session to make an object persistent (and let Hibernate take care of the SQL statements that need to be executed for this transition)."
msgstr ""
#. Tag: para
#: session_api.xml:65
#, no-c-format
msgid "<emphasis>Persistent - a persistent instance has a representation in the database and an identifier value. It might just have been saved or loaded, however, it is by definition in the scope of a Session. Hibernate will detect any changes made to an object in persistent state and synchronize the state with the database when the unit of work completes. Developers do not execute manual UPDATE statements, or DELETE statements when an object should be made transient."
msgstr ""
#. Tag: para
#: session_api.xml:77
#, no-c-format
msgid "<emphasis>Detached - a detached instance is an object that has been persistent, but its Session has been closed. The reference to the object is still valid, of course, and the detached instance might even be modified in this state. A detached instance can be reattached to a new Session at a later point in time, making it (and all the modifications) persistent again. This feature enables a programming model for long running units of work that require user think-time. We call them application transactions, i.e., a unit of work from the point of view of the user."
msgstr ""
#. Tag: para
#: session_api.xml:90
#, no-c-format
msgid "We will now discuss the states and state transitions (and the Hibernate methods that trigger a transition) in more detail."
msgstr ""
#. Tag: title
#: session_api.xml:95
#, no-c-format
msgid "Making objects persistent"
msgstr ""
#. Tag: para
#: session_api.xml:97
#, no-c-format
msgid "Newly instantiated instances of a persistent class are considered <emphasis>transient by Hibernate. We can make a transient instance persistent by associating it with a session:"
msgstr ""
#. Tag: programlisting
#: session_api.xml:102
#, no-c-format
msgid ""
"DomesticCat fritz = new DomesticCat();\n"
"fritz.setColor(Color.GINGER);\n"
"fritz.setSex('M');\n"
"fritz.setName(\"Fritz\");\n"
"Long generatedId = (Long) sess.save(fritz);"
msgstr ""
#. Tag: para
#: session_api.xml:104
#, no-c-format
msgid "If <literal>Cat has a generated identifier, the identifier is generated and assigned to the cat when save() is called. If Cat has an assigned identifier, or a composite key, the identifier should be assigned to the cat instance before calling save(). You can also use persist() instead of save(), with the semantics defined in the EJB3 early draft."
msgstr ""
#. Tag: para
#: session_api.xml:115
#, no-c-format
msgid "<literal>persist() makes a transient instance persistent. However, it does not guarantee that the identifier value will be assigned to the persistent instance immediately, the assignment might happen at flush time. persist() also guarantees that it will not execute an INSERT statement if it is called outside of transaction boundaries. This is useful in long-running conversations with an extended Session/persistence context."
msgstr ""
#. Tag: para
#: session_api.xml:126
#, no-c-format
msgid "<literal>save() does guarantee to return an identifier. If an INSERT has to be executed to get the identifier ( e.g. \"identity\" generator, not \"sequence\"), this INSERT happens immediately, no matter if you are inside or outside of a transaction. This is problematic in a long-running conversation with an extended Session/persistence context."
msgstr ""
#. Tag: para
#: session_api.xml:135
#, no-c-format
msgid "Alternatively, you can assign the identifier using an overloaded version of <literal>save()."
msgstr ""
#. Tag: programlisting
#: session_api.xml:138
#, no-c-format
msgid ""
"DomesticCat pk = new DomesticCat();\n"
"pk.setColor(Color.TABBY);\n"
"pk.setSex('F');\n"
"pk.setName(\"PK\");\n"
"pk.setKittens( new HashSet() );\n"
"pk.addKitten(fritz);\n"
"sess.save( pk, new Long(1234) );"
msgstr ""
#. Tag: para
#: session_api.xml:140
#, no-c-format
msgid "If the object you make persistent has associated objects (e.g. the <literal>kittens collection in the previous example), these objects can be made persistent in any order you like unless you have a NOT NULL constraint upon a foreign key column. There is never a risk of violating foreign key constraints. However, you might violate a NOT NULL constraint if you save() the objects in the wrong order."
msgstr ""
#. Tag: para
#: session_api.xml:148
#, no-c-format
msgid "Usually you do not bother with this detail, as you will normally use Hibernate's <emphasis>transitive persistence feature to save the associated objects automatically. Then, even NOT NULL constraint violations do not occur - Hibernate will take care of everything. Transitive persistence is discussed later in this chapter."
msgstr ""
#. Tag: title
#: session_api.xml:157
#, no-c-format
msgid "Loading an object"
msgstr ""
#. Tag: para
#: session_api.xml:159
#, no-c-format
msgid "The <literal>load() methods of Session provide a way of retrieving a persistent instance if you know its identifier. load() takes a class object and loads the state into a newly instantiated instance of that class in a persistent state."
msgstr ""
#. Tag: programlisting
#: session_api.xml:165
#, no-c-format
msgid "Cat fritz = (Cat) sess.load(Cat.class, generatedId);"
msgstr ""
#. Tag: programlisting
#: session_api.xml:167
#, no-c-format
msgid ""
"// you need to wrap primitive identifiers\n"
"long id = 1234;\n"
"DomesticCat pk = (DomesticCat) sess.load( DomesticCat.class, new Long(id) );"
msgstr ""
#. Tag: para
#: session_api.xml:169
#, no-c-format
msgid "Alternatively, you can load state into a given instance:"
msgstr ""
#. Tag: programlisting
#: session_api.xml:171
#, no-c-format
msgid ""
"Cat cat = new DomesticCat();\n"
"// load pk's state into cat\n"
"sess.load( cat, new Long(pkId) );\n"
"Set kittens = cat.getKittens();"
msgstr ""
#. Tag: para
#: session_api.xml:173
#, no-c-format
msgid "Be aware that <literal>load() will throw an unrecoverable exception if there is no matching database row. If the class is mapped with a proxy, load() just returns an uninitialized proxy and does not actually hit the database until you invoke a method of the proxy. This is useful if you wish to create an association to an object without actually loading it from the database. It also allows multiple instances to be loaded as a batch if batch-size is defined for the class mapping."
msgstr ""
#. Tag: para
#: session_api.xml:182
#, no-c-format
msgid "If you are not certain that a matching row exists, you should use the <literal>get() method which hits the database immediately and returns null if there is no matching row."
msgstr ""
#. Tag: programlisting
#: session_api.xml:186
#, no-c-format
msgid ""
"Cat cat = (Cat) sess.get(Cat.class, id);\n"
"if (cat==null) {\n"
" cat = new Cat();\n"
" sess.save(cat, id);\n"
"}\n"
"return cat;"
msgstr ""
#. Tag: para
#: session_api.xml:188
#, no-c-format
msgid "You can even load an object using an SQL <literal>SELECT ... FOR UPDATE, using a LockMode. See the API documentation for more information."
msgstr ""
#. Tag: programlisting
#: session_api.xml:192
#, no-c-format
msgid "Cat cat = (Cat) sess.get(Cat.class, id, LockMode.UPGRADE);"
msgstr ""
#. Tag: para
#: session_api.xml:194
#, no-c-format
msgid "Any associated instances or contained collections will <emphasis>not be selected FOR UPDATE, unless you decide to specify lock or all as a cascade style for the association."
msgstr ""
#. Tag: para
#: session_api.xml:199
#, no-c-format
msgid "It is possible to re-load an object and all its collections at any time, using the <literal>refresh() method. This is useful when database triggers are used to initialize some of the properties of the object."
msgstr ""
#. Tag: programlisting
#: session_api.xml:204
#, no-c-format
msgid ""
"sess.save(cat);\n"
"sess.flush(); //force the SQL INSERT\n"
"sess.refresh(cat); //re-read the state (after the trigger executes)"
msgstr ""
#. Tag: para
#: session_api.xml:206
#, no-c-format
msgid "How much does Hibernate load from the database and how many SQL <literal>SELECTs will it use? This depends on the fetching strategy. This is explained in ."
msgstr ""
#. Tag: title
#: session_api.xml:213
#, no-c-format
msgid "Querying"
msgstr ""
#. Tag: para
#: session_api.xml:215
#, no-c-format
msgid "If you do not know the identifiers of the objects you are looking for, you need a query. Hibernate supports an easy-to-use but powerful object oriented query language (HQL). For programmatic query creation, Hibernate supports a sophisticated Criteria and Example query feature (QBC and QBE). You can also express your query in the native SQL of your database, with optional support from Hibernate for result set conversion into objects."
msgstr ""
#. Tag: title
#: session_api.xml:224
#, no-c-format
msgid "Executing queries"
msgstr ""
#. Tag: para
#: session_api.xml:226
#, no-c-format
msgid "HQL and native SQL queries are represented with an instance of <literal>org.hibernate.Query. This interface offers methods for parameter binding, result set handling, and for the execution of the actual query. You always obtain a Query using the current Session:"
msgstr ""
#. Tag: programlisting
#: session_api.xml:232
#, no-c-format
msgid ""
"List cats = session.createQuery(\n"
" \"from Cat as cat where cat.birthdate < ?\")\n"
" .setDate(0, date)\n"
" .list();\n"
"\n"
"List mothers = session.createQuery(\n"
" \"select mother from Cat as cat join cat.mother as mother where cat.name = ?\")\n"
" .setString(0, name)\n"
" .list();\n"
"\n"
"List kittens = session.createQuery(\n"
" \"from Cat as cat where cat.mother = ?\")\n"
" .setEntity(0, pk)\n"
" .list();\n"
"\n"
"Cat mother = (Cat) session.createQuery(\n"
" \"select cat.mother from Cat as cat where cat = ?\")\n"
" .setEntity(0, izi)\n"
" .uniqueResult();]]\n"
"\n"
"Query mothersWithKittens = (Cat) session.createQuery(\n"
" \"select mother from Cat as mother left join fetch mother.kittens\");\n"
"Set uniqueMothers = new HashSet(mothersWithKittens.list());"
msgstr ""
#. Tag: para
#: session_api.xml:234
#, no-c-format
msgid "A query is usually executed by invoking <literal>list(). The result of the query will be loaded completely into a collection in memory. Entity instances retrieved by a query are in a persistent state. The uniqueResult() method offers a shortcut if you know your query will only return a single object. Queries that make use of eager fetching of collections usually return duplicates of the root objects, but with their collections initialized. You can filter these duplicates through a Set."
msgstr ""
#. Tag: title
#: session_api.xml:244
#, no-c-format
msgid "Iterating results"
msgstr ""
#. Tag: para
#: session_api.xml:246
#, no-c-format
msgid "Occasionally, you might be able to achieve better performance by executing the query using the <literal>iterate() method. This will usually be the case if you expect that the actual entity instances returned by the query will already be in the session or second-level cache. If they are not already cached, iterate() will be slower than list() and might require many database hits for a simple query, usually 1 for the initial select which only returns identifiers, and n additional selects to initialize the actual instances."
msgstr ""
#. Tag: programlisting
#: session_api.xml:257
#, no-c-format
msgid ""
"// fetch ids\n"
"Iterator iter = sess.createQuery(\"from eg.Qux q order by q.likeliness\").iterate();\n"
"while ( iter.hasNext() ) {\n"
" Qux qux = (Qux) iter.next(); // fetch the object\n"
" // something we couldnt express in the query\n"
" if ( qux.calculateComplicatedAlgorithm() ) {\n"
" // delete the current instance\n"
" iter.remove();\n"
" // dont need to process the rest\n"
" break;\n"
" }\n"
"}"
msgstr ""
#. Tag: title
#: session_api.xml:261
#, no-c-format
msgid "Queries that return tuples"
msgstr ""
#. Tag: para
#: session_api.xml:263
#, no-c-format
msgid "Hibernate queries sometimes return tuples of objects. Each tuple is returned as an array:"
msgstr ""
#. Tag: programlisting
#: session_api.xml:266
#, no-c-format
msgid ""
"Iterator kittensAndMothers = sess.createQuery(\n"
" \"select kitten, mother from Cat kitten join kitten.mother mother\")\n"
" .list()\n"
" .iterator();\n"
"\n"
"while ( kittensAndMothers.hasNext() ) {\n"
" Object[] tuple = (Object[]) kittensAndMothers.next();\n"
" Cat kitten = (Cat) tuple[0];\n"
" Cat mother = (Cat) tuple[1];\n"
" ....\n"
"}"
msgstr ""
#. Tag: title
#: session_api.xml:270
#, no-c-format
msgid "Scalar results"
msgstr ""
#. Tag: para
#: session_api.xml:272
#, no-c-format
msgid "Queries can specify a property of a class in the <literal>select clause. They can even call SQL aggregate functions. Properties or aggregates are considered \"scalar\" results and not entities in persistent state."
msgstr ""
#. Tag: programlisting
#: session_api.xml:277
#, no-c-format
msgid ""
"Iterator results = sess.createQuery(\n"
" \"select cat.color, min(cat.birthdate), count(cat) from Cat cat \" +\n"
" \"group by cat.color\")\n"
" .list()\n"
" .iterator();\n"
"\n"
"while ( results.hasNext() ) {\n"
" Object[] row = (Object[]) results.next();\n"
" Color type = (Color) row[0];\n"
" Date oldest = (Date) row[1];\n"
" Integer count = (Integer) row[2];\n"
" .....\n"
"}"
msgstr ""
#. Tag: title
#: session_api.xml:281
#, no-c-format
msgid "Bind parameters"
msgstr ""
#. Tag: para
#: session_api.xml:283
#, no-c-format
msgid "Methods on <literal>Query are provided for binding values to named parameters or JDBC-style ? parameters. Contrary to JDBC, Hibernate numbers parameters from zero. Named parameters are identifiers of the form :name in the query string. The advantages of named parameters are as follows:"
msgstr ""
#. Tag: para
#: session_api.xml:292
#, no-c-format
msgid "named parameters are insensitive to the order they occur in the query string"
msgstr ""
#. Tag: para
#: session_api.xml:297
#, no-c-format
msgid "they can occur multiple times in the same query"
msgstr ""
#. Tag: para
#: session_api.xml:301
#, no-c-format
msgid "they are self-documenting"
msgstr ""
#. Tag: programlisting
#: session_api.xml:305
#, no-c-format
msgid ""
"//named parameter (preferred)\n"
"Query q = sess.createQuery(\"from DomesticCat cat where cat.name = :name\");\n"
"q.setString(\"name\", \"Fritz\");\n"
"Iterator cats = q.iterate();"
msgstr ""
#. Tag: programlisting
#: session_api.xml:307
#, no-c-format
msgid ""
"//positional parameter\n"
"Query q = sess.createQuery(\"from DomesticCat cat where cat.name = ?\");\n"
"q.setString(0, \"Izi\");\n"
"Iterator cats = q.iterate();"
msgstr ""
#. Tag: programlisting
#: session_api.xml:309
#, no-c-format
msgid ""
"//named parameter list\n"
"List names = new ArrayList();\n"
"names.add(\"Izi\");\n"
"names.add(\"Fritz\");\n"
"Query q = sess.createQuery(\"from DomesticCat cat where cat.name in (:namesList)\");\n"
"q.setParameterList(\"namesList\", names);\n"
"List cats = q.list();"
msgstr ""
#. Tag: title
#: session_api.xml:313
#, no-c-format
msgid "Pagination"
msgstr ""
#. Tag: para
#: session_api.xml:315
#, no-c-format
msgid "If you need to specify bounds upon your result set, that is, the maximum number of rows you want to retrieve and/or the first row you want to retrieve, you can use methods of the <literal>Query interface:"
msgstr ""
#. Tag: programlisting
#: session_api.xml:320
#, no-c-format
msgid ""
"Query q = sess.createQuery(\"from DomesticCat cat\");\n"
"q.setFirstResult(20);\n"
"q.setMaxResults(10);\n"
"List cats = q.list();"
msgstr ""
#. Tag: para
#: session_api.xml:322
#, no-c-format
msgid "Hibernate knows how to translate this limit query into the native SQL of your DBMS."
msgstr ""
#. Tag: title
#: session_api.xml:327
#, no-c-format
msgid "Scrollable iteration"
msgstr ""
#. Tag: para
#: session_api.xml:329
#, no-c-format
msgid "If your JDBC driver supports scrollable <literal>ResultSets, the Query interface can be used to obtain a ScrollableResults object that allows flexible navigation of the query results."
msgstr ""
#. Tag: programlisting
#: session_api.xml:334
#, no-c-format
msgid ""
"Query q = sess.createQuery(\"select cat.name, cat from DomesticCat cat \" +\n"
" \"order by cat.name\");\n"
"ScrollableResults cats = q.scroll();\n"
"if ( cats.first() ) {\n"
"\n"
" // find the first name on each page of an alphabetical list of cats by name\n"
" firstNamesOfPages = new ArrayList();\n"
" do {\n"
" String name = cats.getString(0);\n"
" firstNamesOfPages.add(name);\n"
" }\n"
" while ( cats.scroll(PAGE_SIZE) );\n"
"\n"
" // Now get the first page of cats\n"
" pageOfCats = new ArrayList();\n"
" cats.beforeFirst();\n"
" int i=0;\n"
" while( ( PAGE_SIZE > i++ ) && cats.next() ) pageOfCats.add( cats.get(1) );\n"
"\n"
"}\n"
"cats.close()"
msgstr ""
#. Tag: para
#: session_api.xml:336
#, no-c-format
msgid "Note that an open database connection and cursor is required for this functionality. Use <literal>setMaxResult()/setFirstResult() if you need offline pagination functionality."
msgstr ""
#. Tag: title
#: session_api.xml:343
#, no-c-format
msgid "Externalizing named queries"
msgstr ""
#. Tag: para
#: session_api.xml:345
#, no-c-format
msgid "Queries can also be configured as so called named queries using annotations or Hibernate mapping documents. <literal>@NamedQuery and @NamedQueries can be defined at the class level as seen in . However their definitions are global to the session factory/entity manager factory scope. A named query is defined by its name and the actual query string."
msgstr ""
#. Tag: title
#: session_api.xml:355
#, no-c-format
msgid "Defining a named query using <classname>@NamedQuery"
msgstr ""
#. Tag: programlisting
#: session_api.xml:358
#, no-c-format
msgid ""
"@Entity\n"
"@NamedQuery(name=\"night.moreRecentThan\", query=\"select n from Night n where n.date >= :date\")\n"
"public class Night {\n"
" ...\n"
"}\n"
"\n"
"public class MyDao {\n"
" doStuff() {\n"
" Query q = s.getNamedQuery(\"night.moreRecentThan\");\n"
" q.setDate( \"date\", aMonthAgo );\n"
" List results = q.list();\n"
" ...\n"
" }\n"
" ...\n"
"}"
msgstr ""
#. Tag: para
#: session_api.xml:361
#, no-c-format
msgid "Using a mapping document can be configured using the <literal><query> node. Remember to use a CDATA section if your query contains characters that could be interpreted as markup."
msgstr ""
#. Tag: title
#: session_api.xml:367
#, no-c-format
msgid "Defining a named query using <literal><query>"
msgstr ""
#. Tag: programlisting
#: session_api.xml:370
#, no-c-format
msgid ""
"<query name=\"ByNameAndMaximumWeight\"><![CDATA[\n"
" from eg.DomesticCat as cat\n"
" where cat.name = ?\n"
" and cat.weight > ?\n"
"] ]></query>"
msgstr ""
#. Tag: para
#: session_api.xml:373
#, no-c-format
msgid "Parameter binding and executing is done programatically as seen in <xref linkend=\"example-parameter-binding-named-query\"/>."
msgstr ""
#. Tag: title
#: session_api.xml:377
#, no-c-format
msgid "Parameter binding of a named query"
msgstr ""
#. Tag: programlisting
#: session_api.xml:379
#, no-c-format
msgid ""
"Query q = sess.getNamedQuery(\"ByNameAndMaximumWeight\");\n"
"q.setString(0, name);\n"
"q.setInt(1, minWeight);\n"
"List cats = q.list();"
msgstr ""
#. Tag: para
#: session_api.xml:382
#, no-c-format
msgid "The actual program code is independent of the query language that is used. You can also define native SQL queries in metadata, or migrate existing queries to Hibernate by placing them in mapping files."
msgstr ""
#. Tag: para
#: session_api.xml:387
#, no-c-format
msgid "Also note that a query declaration inside a <literal><hibernate-mapping> element requires a global unique name for the query, while a query declaration inside a <class> element is made unique automatically by prepending the fully qualified name of the class. For example eg.Cat.ByNameAndMaximumWeight."
msgstr ""
#. Tag: title
#: session_api.xml:397
#, no-c-format
msgid "Filtering collections"
msgstr ""
#. Tag: para
#: session_api.xml:399
#, no-c-format
msgid "A collection <emphasis>filter is a special type of query that can be applied to a persistent collection or array. The query string can refer to this, meaning the current collection element."
msgstr ""
#. Tag: programlisting
#: session_api.xml:404
#, no-c-format
msgid ""
"Collection blackKittens = session.createFilter(\n"
" pk.getKittens(), \n"
" \"where this.color = ?\")\n"
" .setParameter( Color.BLACK, Hibernate.custom(ColorUserType.class) )\n"
" .list()\n"
");"
msgstr ""
#. Tag: para
#: session_api.xml:406
#, no-c-format
msgid "The returned collection is considered a bag that is a copy of the given collection. The original collection is not modified. This is contrary to the implication of the name \"filter\", but consistent with expected behavior."
msgstr ""
#. Tag: para
#: session_api.xml:411
#, no-c-format
msgid "Observe that filters do not require a <literal>from clause, although they can have one if required. Filters are not limited to returning the collection elements themselves."
msgstr ""
#. Tag: programlisting
#: session_api.xml:415
#, no-c-format
msgid ""
"Collection blackKittenMates = session.createFilter(\n"
" pk.getKittens(), \n"
" \"select this.mate where this.color = eg.Color.BLACK.intValue\")\n"
" .list();"
msgstr ""
#. Tag: para
#: session_api.xml:417
#, no-c-format
msgid "Even an empty filter query is useful, e.g. to load a subset of elements in a large collection:"
msgstr ""
#. Tag: programlisting
#: session_api.xml:420
#, no-c-format
msgid ""
"Collection tenKittens = session.createFilter(\n"
" mother.getKittens(), \"\")\n"
" .setFirstResult(0).setMaxResults(10)\n"
" .list();"
msgstr ""
#. Tag: title
#: session_api.xml:424
#, no-c-format
msgid "Criteria queries"
msgstr ""
#. Tag: para
#: session_api.xml:426
#, no-c-format
msgid "HQL is extremely powerful, but some developers prefer to build queries dynamically using an object-oriented API, rather than building query strings. Hibernate provides an intuitive <literal>Criteria query API for these cases:"
msgstr ""
#. Tag: programlisting
#: session_api.xml:431
#, no-c-format
msgid ""
"Criteria crit = session.createCriteria(Cat.class);\n"
"crit.add( Restrictions.eq( \"color\", eg.Color.BLACK ) );\n"
"crit.setMaxResults(10);\n"
"List cats = crit.list();"
msgstr ""
#. Tag: para
#: session_api.xml:433
#, no-c-format
msgid "The <literal>Criteria and the associated Example API are discussed in more detail in ."
msgstr ""
#. Tag: title
#: session_api.xml:439
#, no-c-format
msgid "Queries in native SQL"
msgstr ""
#. Tag: para
#: session_api.xml:441
#, no-c-format
msgid "You can express a query in SQL, using <literal>createSQLQuery() and let Hibernate manage the mapping from result sets to objects. You can at any time call session.connection() and use the JDBC Connection directly. If you choose to use the Hibernate API, you must enclose SQL aliases in braces:"
msgstr ""
#. Tag: programlisting
#: session_api.xml:448
#, no-c-format
msgid ""
"List cats = session.createSQLQuery(\"SELECT {cat.*} FROM CAT {cat} WHERE ROWNUM<10\")\n"
" .addEntity(\"cat\", Cat.class)\n"
".list();"
msgstr ""
#. Tag: programlisting
#: session_api.xml:450
#, no-c-format
msgid ""
"List cats = session.createSQLQuery(\n"
" \"SELECT {cat}.ID AS {cat.id}, {cat}.SEX AS {cat.sex}, \" +\n"
" \"{cat}.MATE AS {cat.mate}, {cat}.SUBCLASS AS {cat.class}, ... \" +\n"
" \"FROM CAT {cat} WHERE ROWNUM<10\")\n"
" .addEntity(\"cat\", Cat.class)\n"
".list()"
msgstr ""
#. Tag: para
#: session_api.xml:452
#, no-c-format
msgid "SQL queries can contain named and positional parameters, just like Hibernate queries. More information about native SQL queries in Hibernate can be found in <xref linkend=\"querysql\"/>."
msgstr ""
#. Tag: title
#: session_api.xml:459
#, no-c-format
msgid "Modifying persistent objects"
msgstr ""
#. Tag: para
#: session_api.xml:461
#, no-c-format
msgid "<emphasis>Transactional persistent instances (i.e. objects loaded, saved, created or queried by the Session) can be manipulated by the application, and any changes to persistent state will be persisted when the Session is flushed. This is discussed later in this chapter. There is no need to call a particular method (like update(), which has a different purpose) to make your modifications persistent. The most straightforward way to update the state of an object is to load() it and then manipulate it directly while the Session is open:"
msgstr ""
#. Tag: programlisting
#: session_api.xml:473
#, no-c-format
msgid ""
"DomesticCat cat = (DomesticCat) sess.load( Cat.class, new Long(69) );\n"
"cat.setName(\"PK\");\n"
"sess.flush(); // changes to cat are automatically detected and persisted"
msgstr ""
#. Tag: para
#: session_api.xml:475
#, no-c-format
msgid "Sometimes this programming model is inefficient, as it requires in the same session both an SQL <literal>SELECT to load an object and an SQL UPDATE to persist its updated state. Hibernate offers an alternate approach by using detached instances."
msgstr ""
#. Tag: title
#: session_api.xml:483
#, no-c-format
msgid "Modifying detached objects"
msgstr ""
#. Tag: para
#: session_api.xml:485
#, no-c-format
msgid "Many applications need to retrieve an object in one transaction, send it to the UI layer for manipulation, then save the changes in a new transaction. Applications that use this kind of approach in a high-concurrency environment usually use versioned data to ensure isolation for the \"long\" unit of work."
msgstr ""
#. Tag: para
#: session_api.xml:491
#, no-c-format
msgid "Hibernate supports this model by providing for reattachment of detached instances using the <literal>Session.update() or Session.merge() methods:"
msgstr ""
#. Tag: programlisting
#: session_api.xml:495
#, no-c-format
msgid ""
"// in the first session\n"
"Cat cat = (Cat) firstSession.load(Cat.class, catId);\n"
"Cat potentialMate = new Cat();\n"
"firstSession.save(potentialMate);\n"
"\n"
"// in a higher layer of the application\n"
"cat.setMate(potentialMate);\n"
"\n"
"// later, in a new session\n"
"secondSession.update(cat); // update cat\n"
"secondSession.update(mate); // update mate"
msgstr ""
#. Tag: para
#: session_api.xml:497
#, no-c-format
msgid "If the <literal>Cat with identifier catId had already been loaded by secondSession when the application tried to reattach it, an exception would have been thrown."
msgstr ""
#. Tag: para
#: session_api.xml:502
#, no-c-format
msgid "Use <literal>update() if you are certain that the session does not contain an already persistent instance with the same identifier. Use merge() if you want to merge your modifications at any time without consideration of the state of the session. In other words, update() is usually the first method you would call in a fresh session, ensuring that the reattachment of your detached instances is the first operation that is executed."
msgstr ""
#. Tag: para
#: session_api.xml:510
#, no-c-format
msgid "The application should individually <literal>update() detached instances that are reachable from the given detached instance only if it wants their state to be updated. This can be automated using transitive persistence. See for more information."
msgstr ""
#. Tag: para
#: session_api.xml:516
#, no-c-format
msgid "The <literal>lock() method also allows an application to reassociate an object with a new session. However, the detached instance has to be unmodified."
msgstr ""
#. Tag: programlisting
#: session_api.xml:520
#, no-c-format
msgid ""
"//just reassociate:\n"
"sess.lock(fritz, LockMode.NONE);\n"
"//do a version check, then reassociate:\n"
"sess.lock(izi, LockMode.READ);\n"
"//do a version check, using SELECT ... FOR UPDATE, then reassociate:\n"
"sess.lock(pk, LockMode.UPGRADE);"
msgstr ""
#. Tag: para
#: session_api.xml:522
#, no-c-format
msgid "Note that <literal>lock() can be used with various LockModes. See the API documentation and the chapter on transaction handling for more information. Reattachment is not the only usecase for lock()."
msgstr ""
#. Tag: para
#: session_api.xml:527
#, no-c-format
msgid "Other models for long units of work are discussed in <xref linkend=\"transactions-optimistic\"/>."
msgstr ""
#. Tag: title
#: session_api.xml:532
#, no-c-format
msgid "Automatic state detection"
msgstr ""
#. Tag: para
#: session_api.xml:534
#, no-c-format
msgid "Hibernate users have requested a general purpose method that either saves a transient instance by generating a new identifier or updates/reattaches the detached instances associated with its current identifier. The <literal>saveOrUpdate() method implements this functionality."
msgstr ""
#. Tag: programlisting
#: session_api.xml:540
#, no-c-format
msgid ""
"// in the first session\n"
"Cat cat = (Cat) firstSession.load(Cat.class, catID);\n"
"\n"
"// in a higher tier of the application\n"
"Cat mate = new Cat();\n"
"cat.setMate(mate);\n"
"\n"
"// later, in a new session\n"
"secondSession.saveOrUpdate(cat); // update existing state (cat has a non-null id)\n"
"secondSession.saveOrUpdate(mate); // save the new instance (mate has a null id)"
msgstr ""
#. Tag: para
#: session_api.xml:542
#, no-c-format
msgid "The usage and semantics of <literal>saveOrUpdate() seems to be confusing for new users. Firstly, so long as you are not trying to use instances from one session in another new session, you should not need to use update(), saveOrUpdate(), or merge(). Some whole applications will never use either of these methods."
msgstr ""
#. Tag: para
#: session_api.xml:549
#, no-c-format
msgid "Usually <literal>update() or saveOrUpdate() are used in the following scenario:"
msgstr ""
#. Tag: para
#: session_api.xml:555
#, no-c-format
msgid "the application loads an object in the first session"
msgstr ""
#. Tag: para
#: session_api.xml:559
#, no-c-format
msgid "the object is passed up to the UI tier"
msgstr ""
#. Tag: para
#: session_api.xml:563
#, no-c-format
msgid "some modifications are made to the object"
msgstr ""
#. Tag: para
#: session_api.xml:567
#, no-c-format
msgid "the object is passed back down to the business logic tier"
msgstr ""
#. Tag: para
#: session_api.xml:571
#, no-c-format
msgid "the application persists these modifications by calling <literal>update() in a second session"
msgstr ""
#. Tag: para
#: session_api.xml:576
#, no-c-format
msgid "<literal>saveOrUpdate() does the following:"
msgstr ""
#. Tag: para
#: session_api.xml:580
#, no-c-format
msgid "if the object is already persistent in this session, do nothing"
msgstr ""
#. Tag: para
#: session_api.xml:585
#, no-c-format
msgid "if another object associated with the session has the same identifier, throw an exception"
msgstr ""
#. Tag: para
#: session_api.xml:590
#, no-c-format
msgid "if the object has no identifier property, <literal>save() it"
msgstr ""
#. Tag: para
#: session_api.xml:595
#, no-c-format
msgid "if the object's identifier has the value assigned to a newly instantiated object, <literal>save() it"
msgstr ""
#. Tag: para
#: session_api.xml:600
#, no-c-format
msgid "if the object is versioned by a <literal><version> or <timestamp>, and the version property value is the same value assigned to a newly instantiated object, save() it"
msgstr ""
#. Tag: para
#: session_api.xml:608
#, no-c-format
msgid "otherwise <literal>update() the object"
msgstr ""
#. Tag: para
#: session_api.xml:612
#, no-c-format
msgid "and <literal>merge() is very different:"
msgstr ""
#. Tag: para
#: session_api.xml:616
#, no-c-format
msgid "if there is a persistent instance with the same identifier currently associated with the session, copy the state of the given object onto the persistent instance"
msgstr ""
#. Tag: para
#: session_api.xml:622
#, no-c-format
msgid "if there is no persistent instance currently associated with the session, try to load it from the database, or create a new persistent instance"
msgstr ""
#. Tag: para
#: session_api.xml:628
#, no-c-format
msgid "the persistent instance is returned"
msgstr ""
#. Tag: para
#: session_api.xml:632
#, no-c-format
msgid "the given instance does not become associated with the session, it remains detached"
msgstr ""
#. Tag: title
#: session_api.xml:639
#, no-c-format
msgid "Deleting persistent objects"
msgstr ""
#. Tag: para
#: session_api.xml:641
#, no-c-format
msgid "<literal>Session.delete() will remove an object's state from the database. Your application, however, can still hold a reference to a deleted object. It is best to think of delete() as making a persistent instance, transient."
msgstr ""
#. Tag: programlisting
#: session_api.xml:646
#, no-c-format
msgid "sess.delete(cat);"
msgstr ""
#. Tag: para
#: session_api.xml:648
#, no-c-format
msgid "You can delete objects in any order, without risk of foreign key constraint violations. It is still possible to violate a <literal>NOT NULL constraint on a foreign key column by deleting objects in the wrong order, e.g. if you delete the parent, but forget to delete the children."
msgstr ""
#. Tag: title
#: session_api.xml:656
#, no-c-format
msgid "Replicating object between two different datastores"
msgstr ""
#. Tag: para
#: session_api.xml:658
#, no-c-format
msgid "It is sometimes useful to be able to take a graph of persistent instances and make them persistent in a different datastore, without regenerating identifier values."
msgstr ""
#. Tag: programlisting
#: session_api.xml:662
#, no-c-format
msgid ""
"//retrieve a cat from one database\n"
"Session session1 = factory1.openSession();\n"
"Transaction tx1 = session1.beginTransaction();\n"
"Cat cat = session1.get(Cat.class, catId);\n"
"tx1.commit();\n"
"session1.close();\n"
"\n"
"//reconcile with a second database\n"
"Session session2 = factory2.openSession();\n"
"Transaction tx2 = session2.beginTransaction();\n"
"session2.replicate(cat, ReplicationMode.LATEST_VERSION);\n"
"tx2.commit();\n"
"session2.close();"
msgstr ""
#. Tag: para
#: session_api.xml:664
#, no-c-format
msgid "The <literal>ReplicationMode determines how replicate() will deal with conflicts with existing rows in the database:"
msgstr ""
#. Tag: para
#: session_api.xml:670
#, no-c-format
msgid "<literal>ReplicationMode.IGNORE: ignores the object when there is an existing database row with the same identifier"
msgstr ""
#. Tag: para
#: session_api.xml:675
#, no-c-format
msgid "<literal>ReplicationMode.OVERWRITE: overwrites any existing database row with the same identifier"
msgstr ""
#. Tag: para
#: session_api.xml:680
#, no-c-format
msgid "<literal>ReplicationMode.EXCEPTION: throws an exception if there is an existing database row with the same identifier"
msgstr ""
#. Tag: para
#: session_api.xml:686
#, no-c-format
msgid "<literal>ReplicationMode.LATEST_VERSION: overwrites the row if its version number is earlier than the version number of the object, or ignore the object otherwise"
msgstr ""
#. Tag: para
#: session_api.xml:692
#, no-c-format
msgid "Usecases for this feature include reconciling data entered into different database instances, upgrading system configuration information during product upgrades, rolling back changes made during non-ACID transactions and more."
msgstr ""
#. Tag: title
#: session_api.xml:699
#, no-c-format
msgid "Flushing the Session"
msgstr ""
#. Tag: para
#: session_api.xml:701
#, no-c-format
msgid "Sometimes the <literal>Session will execute the SQL statements needed to synchronize the JDBC connection's state with the state of objects held in memory. This process, called flush, occurs by default at the following points:"
msgstr ""
#. Tag: para
#: session_api.xml:709
#, no-c-format
msgid "before some query executions"
msgstr ""
#. Tag: para
#: session_api.xml:713
#, no-c-format
msgid "from <literal>org.hibernate.Transaction.commit()"
msgstr ""
#. Tag: para
#: session_api.xml:718
#, no-c-format
msgid "from <literal>Session.flush()"
msgstr ""
#. Tag: para
#: session_api.xml:722
#, no-c-format
msgid "The SQL statements are issued in the following order:"
msgstr ""
#. Tag: para
#: session_api.xml:726
#, no-c-format
msgid "all entity insertions in the same order the corresponding objects were saved using <literal>Session.save()"
msgstr ""
#. Tag: para
#: session_api.xml:731
#, no-c-format
msgid "all entity updates"
msgstr ""
#. Tag: para
#: session_api.xml:735
#, no-c-format
msgid "all collection deletions"
msgstr ""
#. Tag: para
#: session_api.xml:739
#, no-c-format
msgid "all collection element deletions, updates and insertions"
msgstr ""
#. Tag: para
#: session_api.xml:743
#, no-c-format
msgid "all collection insertions"
msgstr ""
#. Tag: para
#: session_api.xml:747
#, no-c-format
msgid "all entity deletions in the same order the corresponding objects were deleted using <literal>Session.delete()"
msgstr ""
#. Tag: para
#: session_api.xml:752
#, no-c-format
msgid "An exception is that objects using <literal>native ID generation are inserted when they are saved."
msgstr ""
#. Tag: para
#: session_api.xml:755
#, no-c-format
msgid "Except when you explicitly <literal>flush(), there are absolutely no guarantees about when the Session executes the JDBC calls, only the order in which they are executed. However, Hibernate does guarantee that the Query.list(..) will never return stale or incorrect data."
msgstr ""
#. Tag: para
#: session_api.xml:762
#, no-c-format
msgid "It is possible to change the default behavior so that flush occurs less frequently. The <literal>FlushMode class defines three different modes: only flush at commit time when the Hibernate Transaction API is used, flush automatically using the explained routine, or never flush unless flush() is called explicitly. The last mode is useful for long running units of work, where a Session is kept open and disconnected for a long time (see )."
msgstr ""
#. Tag: programlisting
#: session_api.xml:772
#, no-c-format
msgid ""
"sess = sf.openSession();\n"
"Transaction tx = sess.beginTransaction();\n"
"sess.setFlushMode(FlushMode.COMMIT); // allow queries to return stale state\n"
"\n"
"Cat izi = (Cat) sess.load(Cat.class, id);\n"
"izi.setName(iznizi);\n"
"\n"
"// might return stale data\n"
"sess.find(\"from Cat as cat left outer join cat.kittens kitten\");\n"
"\n"
"// change to izi is not flushed!\n"
"...\n"
"tx.commit(); // flush occurs\n"
"sess.close();"
msgstr ""
#. Tag: para
#: session_api.xml:774
#, no-c-format
msgid "During flush, an exception might occur (e.g. if a DML operation violates a constraint). Since handling exceptions involves some understanding of Hibernate's transactional behavior, we discuss it in <xref linkend=\"transactions\"/>."
msgstr ""
#. Tag: title
#: session_api.xml:781
#, no-c-format
msgid "Transitive persistence"
msgstr ""
#. Tag: para
#: session_api.xml:783
#, no-c-format
msgid "It is quite cumbersome to save, delete, or reattach individual objects, especially if you deal with a graph of associated objects. A common case is a parent/child relationship. Consider the following example:"
msgstr ""
#. Tag: para
#: session_api.xml:788
#, no-c-format
msgid "If the children in a parent/child relationship would be value typed (e.g. a collection of addresses or strings), their life cycle would depend on the parent and no further action would be required for convenient \"cascading\" of state changes. When the parent is saved, the value-typed child objects are saved and when the parent is deleted, the children will be deleted, etc. This works for operations such as the removal of a child from the collection. Since value-typed objects cannot have shared references, Hibernate will detect this and delete the child from the database."
msgstr ""
#. Tag: para
#: session_api.xml:798
#, no-c-format
msgid "Now consider the same scenario with parent and child objects being entities, not value-types (e.g. categories and items, or parent and child cats). Entities have their own life cycle and support shared references. Removing an entity from the collection does not mean it can be deleted), and there is by default no cascading of state from one entity to any other associated entities. Hibernate does not implement <emphasis>persistence by reachability by default."
msgstr ""
#. Tag: para
#: session_api.xml:806
#, no-c-format
msgid "For each basic operation of the Hibernate session - including <literal>persist(), merge(), saveOrUpdate(), delete(), lock(), refresh(), evict(), replicate() - there is a corresponding cascade style. Respectively, the cascade styles are named create, merge, save-update, delete, lock, refresh, evict, replicate. If you want an operation to be cascaded along an association, you must indicate that in the mapping document. For example:"
msgstr ""
#. Tag: programlisting
#: session_api.xml:814
#, no-c-format
msgid "<one-to-one name=\"person\" cascade=\"persist\"/>"
msgstr ""
#. Tag: para
#: session_api.xml:816
#, no-c-format
msgid "Cascade styles my be combined:"
msgstr ""
#. Tag: programlisting
#: session_api.xml:818
#, no-c-format
msgid "<one-to-one name=\"person\" cascade=\"persist,delete,lock\"/>"
msgstr ""
#. Tag: para
#: session_api.xml:820
#, no-c-format
msgid "You can even use <literal>cascade=\"all\" to specify that all operations should be cascaded along the association. The default cascade=\"none\" specifies that no operations are to be cascaded."
msgstr ""
#. Tag: para
#: session_api.xml:825
#, no-c-format
msgid "In case you are using annotatons you probably have noticed the <literal>cascade attribute taking an array of CascadeType as a value. The cascade concept in JPA is very is similar to the transitive persistence and cascading of operations as described above, but with slightly different semantics and cascading types:"
msgstr ""
#. Tag: para
#: session_api.xml:834
#, no-c-format
msgid "<literal>CascadeType.PERSIST: cascades the persist (create) operation to associated entities persist() is called or if the entity is managed"
msgstr ""
#. Tag: para
#: session_api.xml:840
#, no-c-format
msgid "<literal>CascadeType.MERGE: cascades the merge operation to associated entities if merge() is called or if the entity is managed"
msgstr ""
#. Tag: para
#: session_api.xml:846
#, no-c-format
msgid "<literal>CascadeType.REMOVE: cascades the remove operation to associated entities if delete() is called"
msgstr ""
#. Tag: para
#: session_api.xml:851
#, no-c-format
msgid "<literal>CascadeType.REFRESH: cascades the refresh operation to associated entities if refresh() is called"
msgstr ""
#. Tag: para
#: session_api.xml:856
#, no-c-format
msgid "<literal>CascadeType.DETACH: cascades the detach operation to associated entities if detach() is called"
msgstr ""
#. Tag: para
#: session_api.xml:861
#, no-c-format
msgid "<literal>CascadeType.ALL: all of the above"
msgstr ""
#. Tag: para
#: session_api.xml:866
#, no-c-format
msgid "CascadeType.ALL also covers Hibernate specific operations like save-update, lock etc..."
msgstr ""
#. Tag: para
#: session_api.xml:870
#, no-c-format
msgid "A special cascade style, <literal>delete-orphan, applies only to one-to-many associations, and indicates that the delete() operation should be applied to any child object that is removed from the association. Using annotations there is no CascadeType.DELETE-ORPHAN equivalent. Instead you can use the attribute orphanRemoval as seen in . If an entity is removed from a @OneToMany collection or an associated entity is dereferenced from a @OneToOne association, this associated entity can be marked for deletion if orphanRemoval is set to true."
msgstr ""
#. Tag: title
#: session_api.xml:883
#, no-c-format
msgid "<literal>@OneToMany with orphanRemoval"
msgstr ""
#. Tag: programlisting
#: session_api.xml:886
#, no-c-format
msgid ""
"@Entity \n"
"public class Customer {\n"
" private Set<Order> orders;\n"
"\n"
" @OneToMany(cascade=CascadeType.ALL, orphanRemoval=true) \n"
" public Set<Order> getOrders() { return orders; }\n"
"\n"
" public void setOrders(Set<Order> orders) { this.orders = orders; }\n"
"\n"
" [...]\n"
"}\n"
"\n"
"@Entity \n"
"public class Order { ... }\n"
"\n"
"Customer customer = em.find(Customer.class, 1l);\n"
"Order order = em.find(Order.class, 1l);\n"
"customer.getOrders().remove(order); //order will be deleted by cascade"
msgstr ""
#. Tag: para
#: session_api.xml:889
#, no-c-format
msgid "Recommendations:"
msgstr ""
#. Tag: para
#: session_api.xml:893
#, no-c-format
msgid "It does not usually make sense to enable cascade on a many-to-one or many-to-many association. In fact the <literal>@ManyToOne and @ManyToMany don't even offer a orphanRemoval attribute. Cascading is often useful for one-to-one and one-to-many associations."
msgstr ""
#. Tag: para
#: session_api.xml:901
#, no-c-format
msgid "If the child object's lifespan is bounded by the lifespan of the parent object, make it a <emphasis>life cycle object by specifying cascade=\"all,delete-orphan\"(@OneToMany(cascade=CascadeType.ALL, orphanRemoval=true))."
msgstr ""
#. Tag: para
#: session_api.xml:909
#, no-c-format
msgid "Otherwise, you might not need cascade at all. But if you think that you will often be working with the parent and children together in the same transaction, and you want to save yourself some typing, consider using <literal>cascade=\"persist,merge,save-update\"."
msgstr ""
#. Tag: para
#: session_api.xml:917
#, no-c-format
msgid "Mapping an association (either a single valued association, or a collection) with <literal>cascade=\"all\" marks the association as a parent/child style relationship where save/update/delete of the parent results in save/update/delete of the child or children."
msgstr ""
#. Tag: para
#: session_api.xml:923
#, no-c-format
msgid "Furthermore, a mere reference to a child from a persistent parent will result in save/update of the child. This metaphor is incomplete, however. A child which becomes unreferenced by its parent is <emphasis>not automatically deleted, except in the case of a one-to-many association mapped with cascade=\"delete-orphan\". The precise semantics of cascading operations for a parent/child relationship are as follows:"
msgstr ""
#. Tag: para
#: session_api.xml:934
#, no-c-format
msgid "If a parent is passed to <literal>persist(), all children are passed to persist()"
msgstr ""
#. Tag: para
#: session_api.xml:939
#, no-c-format
msgid "If a parent is passed to <literal>merge(), all children are passed to merge()"
msgstr ""
#. Tag: para
#: session_api.xml:944
#, no-c-format
msgid "If a parent is passed to <literal>save(), update() or saveOrUpdate(), all children are passed to saveOrUpdate()"
msgstr ""
#. Tag: para
#: session_api.xml:950
#, no-c-format
msgid "If a transient or detached child becomes referenced by a persistent parent, it is passed to <literal>saveOrUpdate()"
msgstr ""
#. Tag: para
#: session_api.xml:956
#, no-c-format
msgid "If a parent is deleted, all children are passed to <literal>delete()"
msgstr ""
#. Tag: para
#: session_api.xml:961
#, no-c-format
msgid "If a child is dereferenced by a persistent parent, <emphasis>nothing special happens - the application should explicitly delete the child if necessary - unless cascade=\"delete-orphan\", in which case the \"orphaned\" child is deleted."
msgstr ""
#. Tag: para
#: session_api.xml:969
#, no-c-format
msgid "Finally, note that cascading of operations can be applied to an object graph at <emphasis>call time or at flush time. All operations, if enabled, are cascaded to associated entities reachable when the operation is executed. However, save-update and delete-orphan are transitive for all associated entities reachable during flush of the Session."
msgstr ""
#. Tag: title
#: session_api.xml:979
#, no-c-format
msgid "Using metadata"
msgstr ""
#. Tag: para
#: session_api.xml:981
#, no-c-format
msgid "Hibernate requires a rich meta-level model of all entity and value types. This model can be useful to the application itself. For example, the application might use Hibernate's metadata to implement a \"smart\" deep-copy algorithm that understands which objects should be copied (eg. mutable value types) and which objects that should not (e.g. immutable value types and, possibly, associated entities)."
msgstr ""
#. Tag: para
#: session_api.xml:988
#, no-c-format
msgid "Hibernate exposes metadata via the <literal>ClassMetadata and CollectionMetadata interfaces and the Type hierarchy. Instances of the metadata interfaces can be obtained from the SessionFactory."
msgstr ""
#. Tag: programlisting
#: session_api.xml:993
#, no-c-format
msgid ""
"Cat fritz = ......;\n"
"ClassMetadata catMeta = sessionfactory.getClassMetadata(Cat.class);\n"
"\n"
"Object[] propertyValues = catMeta.getPropertyValues(fritz);\n"
"String[] propertyNames = catMeta.getPropertyNames();\n"
"Type[] propertyTypes = catMeta.getPropertyTypes();\n"
"\n"
"// get a Map of all properties which are not collections or associations\n"
"Map namedValues = new HashMap();\n"
"for ( int i=0; i<propertyNames.length; i++ ) {\n"
" if ( !propertyTypes[i].isEntityType() && !propertyTypes[i].isCollectionType() ) {\n"
" namedValues.put( propertyNames[i], propertyValues[i] );\n"
" }\n"
"}"
msgstr ""
Other Hibernate examples (source code examples)
Here is a short list of links related to this Hibernate session_api.pot source code file:
|