From hibernate-commits at lists.jboss.org Wed Jul 14 15:32:05 2010 Content-Type: multipart/mixed; boundary="===============8526693972957753615==" MIME-Version: 1.0 From: hibernate-commits at lists.jboss.org To: hibernate-commits at lists.jboss.org Subject: [hibernate-commits] Hibernate SVN: r19954 - core/trunk/documentation/manual/src/main/docbook/en-US/content. Date: Wed, 14 Jul 2010 15:31:59 -0400 Message-ID: <201007141931.o6EJVx2O011623@svn01.web.mwc.hst.phx2.redhat.com> --===============8526693972957753615== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: hardy.ferentschik Date: 2010-07-14 15:31:59 -0400 (Wed, 14 Jul 2010) New Revision: 19954 Modified: core/trunk/documentation/manual/src/main/docbook/en-US/content/session_a= pi.xml Log: HHH-5379 Added CascadeTypes for annotations Modified: core/trunk/documentation/manual/src/main/docbook/en-US/content/se= ssion_api.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/src/main/docbook/en-US/content/session_= api.xml 2010-07-14 18:59:15 UTC (rev 19953) +++ core/trunk/documentation/manual/src/main/docbook/en-US/content/session_= api.xml 2010-07-14 19:31:59 UTC (rev 19954) @@ -1,4 +1,4 @@ - + - - %BOOK_ENTITIES; - ]> - - Working with objects + Working with objects = - - Hibernate is a full object/relational mapping solution that not on= ly shields - the developer from the details of the underlying database manageme= nt - system, but also offers state management of o= bjects. 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. - + Hibernate is a full object/relational mapping solution that not on= ly + shields the developer from the details of the underlying database manage= ment + system, but also offers 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. = - - In other words, Hibernate application developers should always thi= nk about the - state of their objects, and not necessarily a= bout the - execution of SQL statements. This part is taken care of by Hiberna= te and is only - relevant for the application developer when tuning the performance= of the system. - + In other words, Hibernate application developers should always thi= nk + about the state of their objects, and not necessari= ly + 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. = -
- Hibernate object states +
+ Hibernate object states = - - Hibernate defines and supports the following object states: - + Hibernate defines and supports the following object states: = - - - - Transient - an object is transien= t if it has just - been instantiated using the new ope= rator, and it - is not associated with a Hibernate Session. It has no - persistent representation in the database and no ident= ifier 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 persisten= t (and let Hibernate - take care of the SQL statements that need to be execut= ed for this transition). - - - - - Persistent - a persistent instanc= e 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 sh= ould be made transient. - - - - - Detached - a detached instance is= an object that has been - persistent, but its Session has bee= n closed. The reference - to the object is still valid, of course, and the detac= hed instance might even - be modified in this state. A detached instance can be = reattached to a new - Session at a later point in time, m= aking it (and all the - modifications) persistent again. This feature enables = a programming model for - long running units of work that require user think-tim= e. We call them - application transactions, i.e., a= unit of work from the - point of view of the user. - - - + + + Transient - an object is transient if it + has just been instantiated using the new operat= or, + and it is not associated with a Hibernate Session. + It has no persistent representation in the database and no identif= ier + 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 statemen= ts + that need to be executed for this transition). + = - - We will now discuss the states and state transitions (and the = Hibernate methods that - trigger a transition) in more detail. - + + Persistent - a persistent instance has a + representation in the database and an identifier value. It might j= ust + have been saved or loaded, however, it is by definition in the sco= pe + of a Session. Hibernate will detect any changes + made to an object in persistent state and synchronize the state wi= th + 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. + = -
+ + Detached - a detached instance is an ob= ject + that has been persistent, but its Session has b= een + 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) persist= ent + again. This feature enables a programming model for long running u= nits + 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. + + = -
- Making objects persistent + We will now discuss the states and state transitions (and the + Hibernate methods that trigger a transition) in more detail. +
= - - Newly instantiated instances of a persistent class are conside= red = - transient by Hibernate. We can make a tra= nsient = - instance persistent by associating it wit= h a = - session: - +
+ Making objects persistent = - Newly instantiated instances of a persistent class are considered + transient by Hibernate. We can make a transient + instance persistent by associating it with a + session: + + DomesticCat fritz =3D new DomesticCat(); fritz.setColor(Color.GINGER); fritz.setSex('M'); fritz.setName("Fritz"); -Long generatedId =3D (Long) sess.save(fritz);]]> +Long generatedId =3D (Long) sess.save(fritz); = - - If Cat has a generated identifier, the iden= tifier is - generated and assigned to the cat when save() = - is called. If Cat has an assigned<= /literal> - identifier, or a composite key, the identifier should be assig= ned to = - the cat instance before calling sa= ve(). - You can also use persist() instead of save(), - with the semantics defined in the EJB3 early draft. - + If Cat has a generated identifier, the identi= fier + is generated and assigned to the cat when + save() is called. If Cat has an + assigned identifier, or a composite key, the identi= fier + should be assigned to the cat instance before calli= ng + save(). You can also use persist() + instead of save(), with the semantics defined in the + EJB3 early draft. = - - - - persist() makes a transient instanc= e persistent. = - However, it does not guarantee that the identifier val= ue will be assigned to = - the persistent instance immediately, the assignment mi= ght happen at flush time. = - persist() also guarantees that it w= ill not execute an = - INSERT statement if it is called ou= tside of transaction = - boundaries. This is useful in long-running conversatio= ns with an extended = - Session/persistence context. - - - - - save() does guarantee to return an = identifier. If an INSERT = - has to be executed to get the identifier ( e.g. "ident= ity" generator, not = - "sequence"), this INSERT happens immediately, no matte= r if you are inside or = - outside of a transaction. This is problematic in a lon= g-running conversation = - with an extended Session/persistence context. - - - = + + + persist() makes a transient instance + persistent. However, it does not guarantee that the identifier val= ue + 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. + = - - Alternatively, you can assign the identifier using an overload= ed version - of save(). - + + 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 transacti= on. + This is problematic in a long-running conversation with an extended + Session/persistence context. + + = -Alternatively, you can assign the identifier using an overloaded + version of save(). + + DomesticCat pk =3D new DomesticCat(); pk.setColor(Color.TABBY); pk.setSex('F'); pk.setName("PK"); pk.setKittens( new HashSet() ); pk.addKitten(fritz); -sess.save( pk, new Long(1234) );]]> - = - - If the object you make persistent has associated objects (e.g.= the - kittens collection in the previous example), - these objects can be made persistent in any order you like unl= ess you - have a NOT NULL constraint upon a foreign k= ey column. - There is never a risk of violating foreign key constraints. Ho= wever, you = - might violate a NOT NULL constraint if you - save() the objects in the wrong order. - - = - - Usually you do not bother with this detail, as you will normal= ly use Hibernate's - transitive persistence feature to save th= e 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. - - = -
+sess.save( pk, new Long(1234) ); = -
- Loading an object + If the object you make persistent has associated objects (e.g. t= he + 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. Ther= e 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. = - - The load() methods of Session provide - a way of retrieving a persistent instance if you know its iden= tifier. = - load() takes a class object and loads the s= tate into = - a newly instantiated instance of that class in a persistent st= ate. - + Usually you do not bother with this detail, as you will normally= use + Hibernate's 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. +
= - +
+ Loading an object = -The load() methods of Session + provide a way of retrieving a persistent instance if you know its + identifier. load() takes a class object and loads t= he + state into a newly instantiated instance of that class in a persistent + state. + + Cat fritz =3D (Cat) sess.load(Cat.class,= generatedId); + + // you need to wrap primitive identifiers long id =3D 1234; -DomesticCat pk =3D (DomesticCat) sess.load( DomesticCat.class, new Long(id= ) );]]> +DomesticCat pk =3D (DomesticCat) sess.load( DomesticCat.class, new Long(id= ) ); = - - Alternatively, you can load state into a given instance: - + Alternatively, you can load state into a given instance: = -Cat cat =3D new DomesticCat(); // load pk's state into cat sess.load( cat, new Long(pkId) ); -Set kittens =3D cat.getKittens();]]> +Set kittens =3D cat.getKittens(); = - - Be aware that load() will throw an unrecove= rable 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 pro= xy. 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. - - = - - If you are not certain that a matching row exists, you should = use the = - get() method which hits the database immedi= ately and = - returns null if there is no matching row. - - = - Be aware that load() will throw an unrecovera= ble + 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. + + If you are not certain that a matching row exists, you should use + the get() method which hits the database immediately + and returns null if there is no matching row. + + Cat cat =3D (Cat) sess.get(Cat.class, id= ); if (cat=3D=3Dnull) { cat =3D new Cat(); sess.save(cat, id); } -return cat;]]> +return cat; = - - You can even load an object using an SQL SELECT ... F= OR UPDATE, - using a LockMode. See the API documentation= for more information. - + You can even load an object using an SQL SELECT ... FOR + UPDATE, using a LockMode. See the API + documentation for more information. = - - = - - Any associated instances or contained collections will = - not be selected FOR UPDATE, unless you decide - to specify lock or all a= s a - cascade style for the association. - - = - - It is possible to re-load an object and all its collections at= any time, using the = - refresh() method. This is useful when datab= ase triggers are used to - initialize some of the properties of the object. - - = - + Cat cat =3D (Cat) sess.get(Cat.class, id= , LockMode.UPGRADE); = - - How much does Hibernate load - from the database and how many SQL SELECTs = will it use? This - depends on the fetching strategy. This is= explained in - . - + Any associated instances or contained collections will + not be selected FOR UPDATE, un= less + you decide to specify lock or all as + a cascade style for the association. = -
+ It is possible to re-load an object and all its collections at a= ny + time, using the refresh() method. This is useful wh= en + database triggers are used to initialize some of the properties of the + object. = -
- Querying + sess.save(cat); +sess.flush(); //force the SQL INSERT +sess.refresh(cat); //re-read the state (after the trigger executes) = - - If you do not know the identifiers of the objects you are look= ing for, = - you need a query. Hibernate supports an easy-to-use but powerf= ul object = - oriented query language (HQL). For programmatic query creation= , Hibernate - supports a sophisticated Criteria and Example query feature (Q= BC and QBE). - You can also express your query in the native SQL of your data= base, with - optional support from Hibernate for result set conversion into= objects. - + How much does Hibernate load from the database and how many SQL + SELECTs will it use? This depends on the + fetching strategy. This is explained in . +
= -
- Executing queries +
+ Querying = - - HQL and native SQL queries are represented with an instanc= e of org.hibernate.Query. - This interface offers methods for parameter binding, resul= t set handling, and for the execution - of the actual query. You always obtain a Query using the current - Session: - + 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 conversi= on + into objects. = - + Executing queries + + HQL and native SQL queries are represented with an instance of + 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: + + List cats =3D session.createQuery( + "from Cat as cat where cat.birthdate < ?") .setDate(0, date) .list(); = @@ -309,35 +273,32 @@ = Query mothersWithKittens =3D (Cat) session.createQuery( "select mother from Cat as mother left join fetch mother.kittens"); -Set uniqueMothers =3D new HashSet(mothersWithKittens.list());]]> +Set uniqueMothers =3D new HashSet(mothersWithKittens.list()); = - - A query is usually executed by invoking list(). The - result of the query will be loaded completely into a colle= ction 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 d= uplicates of - the root objects, but with their collections initialized. = You can filter - these duplicates through a Set. - + A query is usually executed by invoking 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 st= ate. + 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 ro= ot + objects, but with their collections initialized. You can filter these + duplicates through a Set. = -
- Iterating results +
+ Iterating results = - - Occasionally, you might be able to achieve better perf= ormance by - executing the query using the iterate() method. - This will usually be the case if you expect that the a= ctual - 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 quer= y, usually - 1 for the initial select which on= ly returns identifiers, - and n additional selects to initi= alize the actual instances. - + Occasionally, you might be able to achieve better performanc= e by + executing the query using the 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 additio= nal + selects to initialize the actual instances. = - // fetch ids Iterator iter =3D sess.createQuery("from eg.Qux q order by q.likeliness").= iterate(); while ( iter.hasNext() ) { Qux qux =3D (Qux) iter.next(); // fetch the object @@ -348,18 +309,16 @@ // dont need to process the rest break; } -}]]> -
- = -
- Queries that return tuples +} +
= - - Hibernate queries sometimes return tuples of objects. = Each tuple - is returned as an array: - +
+ Queries that return tuples = - Hibernate queries sometimes return tuples of objects. Each t= uple + is returned as an array: + + Iterator kittensAndMothers =3D sess.= createQuery( "select kitten, mother from Cat kitten join kitten.mother moth= er") .list() .iterator(); @@ -369,20 +328,18 @@ Cat kitten =3D (Cat) tuple[0]; Cat mother =3D (Cat) tuple[1]; .... -}]]> +} +
= -
+
+ Scalar results = -
- Scalar results + Queries can specify a property of a class in the + select clause. They can even call SQL aggregate + functions. Properties or aggregates are considered "scalar" results + and not entities in persistent state. = - - Queries can specify a property of a class in the select clause. - They can even call SQL aggregate functions. Properties= or aggregates are considered - "scalar" results and not entities in persistent state. - - - Iterator results =3D sess.createQuer= y( "select cat.color, min(cat.birthdate), count(cat) from Cat cat " + "group by cat.color") .list() @@ -394,92 +351,79 @@ Date oldest =3D (Date) row[1]; Integer count =3D (Integer) row[2]; ..... -}]]> +} +
= -
+
+ Bind parameters = -
- Bind parameters + Methods on Query are provided for binding + values to named parameters or JDBC-style ? + parameters. Contrary to JDBC, Hibernate numbers paramete= rs + from zero. Named parameters are identifiers of the form + :name in the query string. The advantages of na= med + parameters are as follows: = - - Methods on Query are provided for b= inding values to - named parameters or JDBC-style ? pa= rameters. = - Contrary to JDBC, Hibernate numbers paramete= rs from zero. - Named parameters are identifiers of the form = :name in = - the query string. The advantages of named parameters a= re as follows: - + + + named parameters are insensitive to the order they occur= in + the query string + = - - - - named parameters are insensitive to the order = they occur in the - query string - - - - - they can occur multiple times in the same query - - - - - they are self-documenting - - - + + they can occur multiple times in the same query + = - + they are self-documenting + + + + //named parameter (preferred) Query q =3D sess.createQuery("from DomesticCat cat where cat.name =3D :nam= e"); q.setString("name", "Fritz"); -Iterator cats =3D q.iterate();]]> +Iterator cats =3D q.iterate(); = - //positional parameter Query q =3D sess.createQuery("from DomesticCat cat where cat.name =3D ?"); q.setString(0, "Izi"); -Iterator cats =3D q.iterate();]]> +Iterator cats =3D q.iterate(); = - //named parameter list List names =3D new ArrayList(); names.add("Izi"); names.add("Fritz"); Query q =3D sess.createQuery("from DomesticCat cat where cat.name in (:nam= esList)"); q.setParameterList("namesList", names); -List cats =3D q.list();]]> +List cats =3D q.list(); +
= -
+
+ Pagination = -
- Pagination + 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 y= ou + want to retrieve, you can use methods of the Query + interface: = - - If you need to specify bounds upon your result set, th= at 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 Query interface: - - - Query q =3D sess.createQuery("from D= omesticCat cat"); q.setFirstResult(20); q.setMaxResults(10); -List cats =3D q.list();]]> +List cats =3D q.list(); = - - Hibernate knows how to translate this limit query into= the native - SQL of your DBMS. - + Hibernate knows how to translate this limit query into the + native SQL of your DBMS. +
= -
+
+ Scrollable iteration = -
- Scrollable iteration + If your JDBC driver supports scrollable + ResultSets, the Query interf= ace + can be used to obtain a ScrollableResults object + that allows flexible navigation of the query results. = - - If your JDBC driver supports scrollable Resul= tSets, the - Query interface can be used to obta= in a - ScrollableResults object that allow= s flexible - navigation of the query results. - - - Query q =3D sess.createQuery("select= cat.name, cat from DomesticCat cat " + "order by cat.name"); ScrollableResults cats =3D q.scroll(); if ( cats.first() ) { @@ -496,215 +440,188 @@ pageOfCats =3D new ArrayList(); cats.beforeFirst(); int i=3D0; - while( ( PAGE_SIZE > i++ ) && cats.next() ) pageOfCats.add( cats.get(1= ) ); + while( ( PAGE_SIZE > i++ ) && cats.next() ) pageOfCats.add(= cats.get(1) ); = } -cats.close()]]> +cats.close() = - - Note that an open database connection and cursor is re= quired for this - functionality. Use setMaxResult()/<= literal>setFirstResult() - if you need offline pagination functionality. - + Note that an open database connection and cursor is required= for + this functionality. Use + setMaxResult()/setFirstResult() + if you need offline pagination functionality. +
= -
+
+ Externalizing named queries = -
- Externalizing named queries + You can also define named queries in the mapping document. + Remember to use a CDATA section if your query + contains characters that could be interpreted as markup. = - - You can also define named queries in the mapping docum= ent. Remember to use a - CDATA section if your query contain= s characters that could - be interpreted as markup. - - - <query name=3D"ByNameAndMaximumWei= ght"><![CDATA[ from eg.DomesticCat as cat where cat.name =3D ? - and cat.weight > ? -] ]>]]> + and cat.weight > ? +] ]></query> = - - Parameter binding and executing is done programaticall= y: - + Parameter binding and executing is done programatically: = - Query q =3D sess.getNamedQuery("ByNa= meAndMaximumWeight"); q.setString(0, name); q.setInt(1, minWeight); -List cats =3D q.list();]]> +List cats =3D q.list(); = - - The actual program code is independent of the query la= nguage that - is used. You can also define native SQL queries in met= adata, or migrate - existing queries to Hibernate by placing them in mappi= ng files. - + 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. = - - Also note that a query declaration inside a &= lt;hibernate-mapping> - element requires a global unique name for the query, w= hile a query declaration inside a - <class> element is made uniqu= e automatically by prepending the - fully qualified name of the class. For example - eg.Cat.ByNameAndMaximumWeight. - + Also note that a query declaration inside a + <hibernate-mapping> element requires a gl= obal + unique name for the query, while a query declaration inside a + <class> element is made unique automatica= lly + by prepending the fully qualified name of the class. For example + eg.Cat.ByNameAndMaximumWeight. +
+
= -
+
+ Filtering collections = -
+ A collection filter is a special type of + query that can be applied to a persistent collection or array. The q= uery + string can refer to this, meaning the current + collection element. = -
- Filtering collections - - A collection filter is a special type= of query that can be applied to - a persistent collection or array. The query string can ref= er to this, - meaning the current collection element. - - - Collection blackKittens =3D session.cr= eateFilter( pk.getKittens(), = "where this.color =3D ?") .setParameter( Color.BLACK, Hibernate.custom(ColorUserType.class) ) .list() -);]]> - = - - 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. - +); = - - Observe that filters do not require a from clause, although they can have - one if required. Filters are not limited to returning the = collection elements themselves. - + 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. = - Observe that filters do not require a from + clause, although they can have one if required. Filters are not limi= ted + to returning the collection elements themselves. + + Collection blackKittenMates =3D sessio= n.createFilter( pk.getKittens(), = "select this.mate where this.color =3D eg.Color.BLACK.intValue") - .list();]]> + .list(); = - - Even an empty filter query is useful, e.g. to load a subse= t of elements in a - large collection: - + Even an empty filter query is useful, e.g. to load a subset of + elements in a large collection: = - Collection tenKittens =3D session.crea= teFilter( mother.getKittens(), "") .setFirstResult(0).setMaxResults(10) - .list();]]> + .list(); +
= -
+
+ Criteria queries = -
- Criteria queries + HQL is extremely powerful, but some developers prefer to build + queries dynamically using an object-oriented API, rather than buildi= ng + query strings. Hibernate provides an intuitive + Criteria query API for these cases: = - - HQL is extremely powerful, but some developers prefer to b= uild queries dynamically - using an object-oriented API, rather than building query s= trings. Hibernate provides - an intuitive Criteria query API for the= se cases: - - - Criteria crit =3D session.createCriter= ia(Cat.class); crit.add( Restrictions.eq( "color", eg.Color.BLACK ) ); crit.setMaxResults(10); -List cats =3D crit.list();]]> - = - - The Criteria and the associated Example - API are discussed in more detail in . - +List cats =3D crit.list(); = -
+ The Criteria and the associated + Example API are discussed in more detail in . +
= -
- Queries in native SQL +
+ Queries in native SQL = - - You can express a query in SQL, using createSQLQu= ery() and - let Hibernate manage the mapping from result sets to objec= ts. - You can at any time call session.connection() and - use the JDBC Connection directly. If yo= u choose to use the - Hibernate API, you must enclose SQL aliases in braces: - + You can express a query in SQL, using + createSQLQuery() and let Hibernate manage the map= ping + 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: = - List cats =3D session.createSQLQuery("= SELECT {cat.*} FROM CAT {cat} WHERE ROWNUM<10") .addEntity("cat", Cat.class) -.list();]]> - = - + + List cats =3D session.createSQLQuery( "SELECT {cat}.ID AS {cat.id}, {cat}.SEX AS {cat.sex}, " + "{cat}.MATE AS {cat.mate}, {cat}.SUBCLASS AS {cat.class}, ... "= + - "FROM CAT {cat} WHERE ROWNUM<10") + "FROM CAT {cat} WHERE ROWNUM<10") .addEntity("cat", Cat.class) -.list()]]> +.list() = - - SQL queries can contain named and positional parameters, j= ust like Hibernate queries. - More information about native SQL queries in Hibernate can= be found in - . - - -
- + SQL queries can contain named and positional parameters, just = like + Hibernate queries. More information about native SQL queries in + Hibernate can be found in .
+
= -
- Modifying persistent objects +
+ Modifying persistent objects = - - 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 t= his chapter. There is no need - to call a particular method (like update(),= which has a different - purpose) to make your modifications persistent. The most strai= ghtforward way to update - the state of an object is to load() it - and then manipulate it directly while the Session is open: - + 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 purpos= e) + to make your modifications persistent. The most straightforward way to + update the state of an object is to load() it and t= hen + manipulate it directly while the Session is + open: = - DomesticCat cat =3D (DomesticCat) sess.l= oad( Cat.class, new Long(69) ); cat.setName("PK"); -sess.flush(); // changes to cat are automatically detected and persisted]= ]> +sess.flush(); // changes to cat are automatically detected and persisted<= /programlisting> = - - Sometimes this programming model is inefficient, as it require= s in the same session both an SQL - SELECT to load an object and an SQL UPDATE - to persist its updated state. Hibernate offers an - alternate approach by using detached instances. - + Sometimes this programming model is inefficient, as it requires = in + the same session both an SQL SELECT to load an obje= ct + and an SQL UPDATE to persist its updated state. + Hibernate offers an alternate approach by using detached instances. = - - Hibernate does not offer its own API for direct execution of - UPDATE or DELETE stateme= nts. Hibernate is a - state management service, you do not have= to think in - statements to use it. JDBC is a perfect A= PI for executing - SQL statements, you can get a JDBC Connection at any time - by calling session.connection(). Furthermor= e, the notion - of mass operations conflicts with object/relational mapping fo= r online - transaction processing-oriented applications. Future versions = of Hibernate - can, however, provide special mass operation functions. See - for some possible batch operation tricks. - - + + Hibernate does not offer its own API for direct execution of + UPDATE or DELETE statements. + Hibernate is a state management service, you do= not + have to think in statements to use it. JDBC is a + perfect API for executing SQL statements, you can get a JDBC + Connection at any time by calling + session.connection(). Furthermore, the notion of = mass + operations conflicts with object/relational mapping for online + transaction processing-oriented applications. Future versions of + Hibernate can, however, provide special mass operation functions. See + for some possible batch operation + tricks. + +
= -
+
+ Modifying detached objects = -
- Modifying detached objects + Many applications need to retrieve an object in one transaction, + send it to the UI layer for manipulation, then save the changes in a n= ew + 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. = - - Many applications need to retrieve an object in one transactio= n, send it to the - UI layer for manipulation, then save the changes in a new tran= saction. - Applications that use this kind of approach in a high-concurre= ncy environment - usually use versioned data to ensure isolation for the "long" = unit of work. - + Hibernate supports this model by providing for reattachment of + detached instances using the Session.update() or + Session.merge() methods: = - - Hibernate supports this model by providing for reattachment of= detached instances - using the Session.update() or Sess= ion.merge() - methods: - - - // in the first session Cat cat =3D (Cat) firstSession.load(Cat.class, catId); Cat potentialMate =3D new Cat(); firstSession.save(potentialMate); @@ -714,66 +631,57 @@ = // later, in a new session secondSession.update(cat); // update cat -secondSession.update(mate); // update mate]]> +secondSession.update(mate); // update mate = - - If the Cat with identifier catId had already - been loaded by secondSession when the appli= cation tried to - reattach it, an exception would have been thrown. - + If the Cat with identifier + catId had already been loaded by + secondSession when the application tried to reattach + it, an exception would have been thrown. = - - Use update() if you are certain that the se= ssion does - not contain an already persistent instance with the same ident= ifier. Use - merge() if you want to merge your modificat= ions at any time - without consideration of the state of the session. In other wo= rds, update() - is usually the first method you would call in a fresh session,= ensuring that - the reattachment of your detached instances is the first opera= tion that is executed. - + Use update() if you are certain that the sess= ion + does not contain an already persistent instance with the same identifi= er. + 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 wou= ld + call in a fresh session, ensuring that the reattachment of your detach= ed + instances is the first operation that is executed. = - - The application should individually 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. - + The application should individually 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. = - - The lock() method also allows an applicatio= n to reassociate - an object with a new session. However, the detached instance h= as to be unmodified. - + The lock() method also allows an application = to + reassociate an object with a new session. However, the detached instan= ce + has to be unmodified. = - //just reassociate: sess.lock(fritz, LockMode.NONE); //do a version check, then reassociate: sess.lock(izi, LockMode.READ); //do a version check, using SELECT ... FOR UPDATE, then reassociate: -sess.lock(pk, LockMode.UPGRADE);]]> +sess.lock(pk, LockMode.UPGRADE); = - - Note that lock() can be used with various - LockModes. See the API documentation and the - chapter on transaction handling for more information. Reattach= ment is not - the only usecase for lock(). - + Note that lock() can be used with various + LockModes. See the API documentation and the chapte= r on + transaction handling for more information. Reattachment is not the only + usecase for lock(). = - - Other models for long units of work are discussed in . - + Other models for long units of work are discussed in . +
= -
+
+ Automatic state detection = -
- Automatic state detection + Hibernate users have requested a general purpose method that eit= her + saves a transient instance by generating a new identifier or + updates/reattaches the detached instances associated with its current + identifier. The saveOrUpdate() method implements th= is + functionality. = - - Hibernate users have requested a general purpose method that e= ither saves a - transient instance by generating a new identifier or updates/r= eattaches - the detached instances associated with its current identifier. - The saveOrUpdate() method implements this f= unctionality. - - - // in the first session Cat cat =3D (Cat) firstSession.load(Cat.class, catID); = // in a higher tier of the application @@ -782,157 +690,129 @@ = // later, in a new session secondSession.saveOrUpdate(cat); // update existing state (cat has a non= -null id) -secondSession.saveOrUpdate(mate); // save the new instance (mate has a nu= ll id)]]> +secondSession.saveOrUpdate(mate); // save the new instance (mate has a nu= ll id) = - - The usage and semantics of saveOrUpdate() s= eems to be confusing - for new users. Firstly, so long as you are not trying to use i= nstances from one session - in another new session, you should not need to use up= date(), - saveOrUpdate(), or merge(). Some whole - applications will never use either of these methods. - + The usage and semantics of saveOrUpdate() see= ms + 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 eit= her + of these methods. = - - Usually update() or saveOrUpdate()= are used in - the following scenario: - + Usually update() or + saveOrUpdate() are used in the following + scenario: = - - - - the application loads an object in the first session - - - - - the object is passed up to the UI tier - - - - - some modifications are made to the object - - - - - the object is passed back down to the business logic t= ier - - - - - the application persists these modifications by calling - update() in a second session - - - + + + the application loads an object in the first session + = - - saveOrUpdate() does the following: - + + the object is passed up to the UI tier + = - - - - if the object is already persistent in this session, d= o nothing - - - - - if another object associated with the session has the = same identifier, = - throw an exception - - - - - if the object has no identifier property, sav= e() it - - - - - if the object's identifier has the value assigned to a= newly instantiated - object, save() it - - - - - if the object is versioned by a <version&g= t; or - <timestamp>, and the version = property value - is the same value assigned to a newly instantiated obj= ect, = - save() it - - - - - otherwise update() the object - - - + + some modifications are made to the object + = - - and merge() is very different: - + + the object is passed back down to the business logic tier + = - - - - if there is a persistent instance with the same identi= fier currently = - associated with the session, copy the state of the giv= en object onto = - the persistent instance - - - - - if there is no persistent instance currently associate= d with the session, = - try to load it from the database, or create a new pers= istent instance - - - - - the persistent instance is returned - - - - - the given instance does not become associated with the= session, it - remains detached - - - + + the application persists these modifications by calling + update() in a second session + + = -
+ saveOrUpdate() does the following: = -
- Deleting persistent objects + + + if the object is already persistent in this session, do + nothing + = - - Session.delete() will remove an object's st= ate from the database. - Your application, however, can still hold a reference to a del= eted object. - It is best to think of delete() as making a= persistent instance, - transient. - + + if another object associated with the session has the same + identifier, throw an exception + = - + + if the object has no identifier property, + save() it + = - - You can delete objects in any order, without risk of foreign k= ey - constraint violations. It is still possible to violate a 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. - + + if the object's identifier has the value assigned to a newly + instantiated object, save() it + = -
- = -
- Replicating object between two different datastores - = - - It is sometimes useful to be able to take a graph of persistent i= nstances - and make them persistent in a different datastore, without regene= rating identifier - values. - - = - + if the object is versioned by a + <version> or + <timestamp>, and the version property val= ue + is the same value assigned to a newly instantiated object, + save() it + + + + otherwise update() the object + + + + and merge() is very different: + + + + 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 + + + + if there is no persistent instance currently associated with= the + session, try to load it from the database, or create a new persist= ent + instance + + + + the persistent instance is returned + + + + the given instance does not become associated with the sessi= on, + it remains detached + + +
+ +
+ Deleting persistent objects + + Session.delete() will remove an object's state + from the database. Your application, however, can still hold a referen= ce + to a deleted object. It is best to think of delete() as + making a persistent instance, transient. + + sess.delete(cat); + + You can delete objects in any order, without risk of foreign key + constraint violations. It is still possible to violate a 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 t= he + children. +
+ +
+ Replicating object between two different datastores + + 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. + + //retrieve a cat from one database Session session1 =3D factory1.openSession(); Transaction tx1 =3D session1.beginTransaction(); Cat cat =3D session1.get(Cat.class, catId); @@ -944,140 +824,117 @@ Transaction tx2 =3D session2.beginTransaction(); session2.replicate(cat, ReplicationMode.LATEST_VERSION); tx2.commit(); -session2.close();]]> +session2.close(); = - - The ReplicationMode determines how replicate() - will deal with conflicts with existing rows in the database: - - = - - - - ReplicationMode.IGNORE: ignores the= object when there is - an existing database row with the same identifier - - - - - ReplicationMode.OVERWRITE: overwrit= es any existing database = - row with the same identifier - - - - - ReplicationMode.EXCEPTION: throws a= n exception if there is - an existing database row with the same identifier - - - - - ReplicationMode.LATEST_VERSION: ove= rwrites the row if its - version number is earlier than the version number of t= he object, or ignore - the object otherwise - - - + The ReplicationMode determines how + replicate() will deal with conflicts with existing = rows + in the database: = - - Usecases for this feature include reconciling data entered int= o different database - instances, upgrading system configuration information during p= roduct upgrades, - rolling back changes made during non-ACID transactions and mor= e. - - = -
+ + + ReplicationMode.IGNORE: ignores the object + when there is an existing database row with the same identifier + = -
- Flushing the Session + + ReplicationMode.OVERWRITE: overwrites any + existing database row with the same identifier + = - - Sometimes the Session will execute the SQL = statements = - needed to synchronize the JDBC connection's state with the sta= te of objects held in = - memory. This process, called flush, occur= s by default at the following = - points: - + + ReplicationMode.EXCEPTION: throws an + exception if there is an existing database row with the same + identifier + = - - - - before some query executions - - - - - from org.hibernate.Transaction.commit() - - - - - from Session.flush() - - - + + ReplicationMode.LATEST_VERSION: overwrites + the row if its version number is earlier than the version number of + the object, or ignore the object otherwise + + = - - The SQL statements are issued in the following order: - + Usecases for this feature include reconciling data entered into + different database instances, upgrading system configuration informati= on + during product upgrades, rolling back changes made during non-ACID + transactions and more. +
= - - - - all entity insertions in the same order the correspond= ing objects - were saved using Session.save() - - - - - all entity updates - - - - - all collection deletions - - - - - all collection element deletions, updates and insertio= ns - - - - - all collection insertions - - - - - all entity deletions in the same order the correspondi= ng objects - were deleted using Session.delete() - - - +
+ Flushing the Session = - - An exception is that objects using native I= D generation are = - inserted when they are saved. - + Sometimes the 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: = - - Except when you explicitly flush(), there a= re absolutely no = - guarantees about when the Sessio= n executes = - the JDBC calls, only the order in which t= hey are executed. - However, Hibernate does guarantee that the Query.list= (..) = - will never return stale or incorrect data. - + + + before some query executions + = - - It is possible to change the default behavior so that flush oc= curs less frequently. - The 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 n= ever 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 ). - + + from + org.hibernate.Transaction.commit() + = - + from Session.flush() + + + + The SQL statements are issued in the following order: + + + + all entity insertions in the same order the corresponding + objects were saved using Session.save() + + + + all entity updates + + + + all collection deletions + + + + all collection element deletions, updates and insertions + + + + all collection insertions + + + + all entity deletions in the same order the corresponding obj= ects + were deleted using Session.delete() + + + + An exception is that objects using native ID + generation are inserted when they are saved. + + Except when you explicitly flush(), there are + absolutely no guarantees about when the + Session executes the JDBC calls, only the + order in which they are executed. However, Hibern= ate + does guarantee that the Query.list(..) will never + return stale or incorrect data. + + It is possible to change the default behavior so that flush occu= rs + less frequently. The 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 w= ork, + where a Session is kept open and disconnected for a + long time (see ). + + sess =3D sf.openSession(); Transaction tx =3D sess.beginTransaction(); sess.setFlushMode(FlushMode.COMMIT); // allow queries to return stale state = @@ -1090,188 +947,245 @@ // change to izi is not flushed! ... tx.commit(); // flush occurs -sess.close();]]> +sess.close(); = - - During flush, an exception might occur (e.g. if a DML operatio= n violates a constraint). - Since handling exceptions involves some understanding of Hiber= nate's transactional = - behavior, we discuss it in . - + 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 + . +
= -
+
+ Transitive persistence = -
- Transitive persistence + 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: = - - It is quite cumbersome to save, delete, or reattach individual= objects, - especially if you deal with a graph of associated objects. A c= ommon case is - a parent/child relationship. Consider the following example: - + If the children in a parent/child relationship would be value ty= ped + (e.g. a collection of addresses or strings), their life cycle would de= pend + 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 w= ill + be deleted, etc. This works for operations such as the removal of a ch= ild + from the collection. Since value-typed objects cannot have shared + references, Hibernate will detect this and delete the child from the + database. = - - 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 sa= ved 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 c= ollection. - Since value-typed objects cannot have shared - references, Hibernate will detect this and delete the child fr= om the database. - + Now consider the same scenario with parent and child objects bei= ng + entities, not value-types (e.g. categories and items, or parent and ch= ild + cats). Entities have their own life cycle and support shared reference= s. + 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 o= ther + associated entities. Hibernate does not implement persistenc= e by + reachability by default. = - - Now consider the same scenario with parent and child objects b= eing entities, - not value-types (e.g. categories and items, or parent and chil= d cats). Entities - have their own life cycle and support shared references. Remo= ving 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 ent= ities. Hibernate - does not implement persistence by reachability by default. - + For each basic operation of the Hibernate session - including + persist(), merge(), saveOrUpdate(), delete(), lock(), refresh= (), + evict(), replicate() - there is a corresponding cascade styl= e. + 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 indica= te + that in the mapping document. For example: = - - For each basic operation of the Hibernate session - including = persist(), merge(), - saveOrUpdate(), delete(), lock(), refresh(), evict(), replicat= e() - 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 indica= te that in the mapping - document. For example: - - = - ]]> - = - - Cascade styles my be combined: - - = - ]]> - = - - You can even use cascade=3D"all" to specify= that all - operations should be cascaded along the association. The defau= lt cascade=3D"none" - specifies that no operations are to be cascaded. - - = - - A special cascade style, delete-orphan, app= lies only to one-to-many - associations, and indicates that the delete() operation should - be applied to any child object that is removed from the associ= ation. - + <one-to-one name=3D"person" cascade=3D= "persist"/> = + Cascade styles my be combined: = - - Recommendations: - + <one-to-one name=3D"person" cascade=3D= "persist,delete,lock"/> = - - - - It does not usually make sense to enable cascade on a = <many-to-one> - or <many-to-many> association= . Cascade is often useful for = - <one-to-one> and <= ;one-to-many> - associations. - - - - - If the child object's lifespan is bounded by the lifes= pan of the parent - object, make it a life cycle object by specifying - cascade=3D"all,delete-orphan". - - - - - Otherwise, you might not need cascade at all. But if y= ou think that you will often be - working with the parent and children together in the s= ame transaction, and you want to save = - yourself some typing, consider using cascade= =3D"persist,merge,save-update". - - - + You can even use cascade=3D"all" to specify t= hat + all operations should be cascaded along the + association. The default cascade=3D"none" specifies= that + no operations are to be cascaded. = - - Mapping an association (either a single valued association, or= a collection) with = - cascade=3D"all" marks the association as a = - parent/child style relationship where sav= e/update/delete of the = - parent results in save/update/delete of the child or children. - - - Furthermore, a mere reference to a child from a persistent par= ent will result in = - save/update of the child. This metaphor is incomplete, however= . A child which becomes = - unreferenced by its parent is not automat= ically deleted, except = - in the case of a <one-to-many> associ= ation mapped with - cascade=3D"delete-orphan". The precise sema= ntics of cascading = - operations for a parent/child relationship are as follows: - + In case you are using annotatons you probably have noticed the + 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 a= nd + cascading types: = - - - - If a parent is passed to persist(),= all children are passed to = - persist() - - - - - If a parent is passed to merge(), a= ll children are passed to = - merge() - - - - - If a parent is passed to save(), update() or = - saveOrUpdate(), all children are pa= ssed to saveOrUpdate() - - - - - If a transient or detached child becomes referenced by= a persistent parent, = - it is passed to saveOrUpdate() - - - - - If a parent is deleted, all children are passed to delete() - - - - - If a child is dereferenced by a persistent parent, nothing - special happens - the application should ex= plicitly delete = - the child if necessary - unless cascade=3D"de= lete-orphan", = - in which case the "orphaned" child is deleted. - - - + + + CascadeType.PERSIST: cascades the persist + (create) operation to associated entities persist() is called or if + the entity is managed + = - - Finally, note that cascading of operations can be applied to a= n object graph at - 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 fl= ush of the - Session. - + + CascadeType.MERGE: cascades the merge + operation to associated entities if merge() is called or if the en= tity + is managed + = -
+ + CascadeType.REMOVE: cascades the remove + operation to associated entities if delete() is called + = -
- Using metadata + + CascadeType.REFRESH: cascades the refresh + operation to associated entities if refresh() is called + = - - Hibernate requires a rich meta-level model of all entity and v= alue types. = - This model can be useful to the application itself. For exampl= e, the application - might use Hibernate's metadata to implement a "smart" deep-cop= y algorithm that understands - which objects should be copied (eg. mutable value types) and w= hich objects that should not (e.g. = - immutable value types and, possibly, associated entities). - - - Hibernate exposes metadata via the ClassMetadata and - CollectionMetadata interfaces and the Type - hierarchy. Instances of the metadata interfaces can be obtaine= d from the = - SessionFactory. - + + CascadeType.DETACH: cascades the detach + operation to associated entities if detach() is called + = - + CascadeType.ALL: all of the above + + + + + CascadeType.ALL also covers Hibernate specific operations like + save-update, lock etc... + + + A special cascade style, delete-orphan, appli= es + 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 i= s no + CascadeType.DELETE-ORPHAN equivalent. Instead you c= an + 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. + + + <literal>@OneToMany</literal> with + <literal>orphanRemoval</literal> + + @Entity = +public class Customer { + private Set<Order> orders; + + @OneToMany(cascade=3DCascadeType.ALL, orphanRemoval=3Dtrue) = + public Set<Order> getOrders() { return orders; } + + public void setOrders(Set<Order> orders) { this.orders =3D orders= ; } + + [...] +} + +(a)Entity = +public class Order { ... } + +Customer customer =3D em.find(Customer.class, 1l); +Order order =3D em.find(Order.class, 1l); +customer.getOrders().remove(order); //order will be deleted by cascade + + + Recommendations: + + + + It does not usually make sense to enable cascade on a + many-to-one or many-to-many association. In fact the + @ManyToOne and @ManyToMany d= on't + even offer a orphanRemoval attribute. Cascading= is + often useful for one-to-one and one-to-many associations. + + + + If the child object's lifespan is bounded by the lifespan of= the + parent object, make it a life cycle object by + specifying + cascade=3D"all,delete-orphan"(@OneToMany(cascade= =3DCascadeType.ALL, + orphanRemoval=3Dtrue)). + + + + Otherwise, you might not need cascade at all. But if you thi= nk + that you will often be working with the parent and children togeth= er + in the same transaction, and you want to save yourself some typing, + consider using + cascade=3D"persist,merge,save-update". + + + + Mapping an association (either a single valued association, or a + collection) with cascade=3D"all" marks the associat= ion as + a parent/child style relationship where + save/update/delete of the parent results in save/update/delete of the + child or children. + + 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 + not automatically deleted, except in the case of a + one-to-many association mapped with + cascade=3D"delete-orphan". The precise semantics of + cascading operations for a parent/child relationship are as + follows: + + + + If a parent is passed to persist(), all + children are passed to persist() + + + + If a parent is passed to merge(), all + children are passed to merge() + + + + If a parent is passed to save(), + update() or saveOrUpdate(), = all + children are passed to saveOrUpdate() + + + + If a transient or detached child becomes referenced by a + persistent parent, it is passed to + saveOrUpdate() + + + + If a parent is deleted, all children are passed to + delete() + + + + If a child is dereferenced by a persistent parent, + nothing special happens - the application sho= uld + explicitly delete the child if necessary - unless + cascade=3D"delete-orphan", in which case the + "orphaned" child is deleted. + + + + Finally, note that cascading of operations can be applied to an + object graph at 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. +
+ +
+ Using metadata + + Hibernate requires a rich meta-level model of all entity and val= ue + 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 (e= g. + mutable value types) and which objects that should not (e.g. immutable + value types and, possibly, associated entities). + + Hibernate exposes metadata via the ClassMetadata + and CollectionMetadata interfaces and the + Type hierarchy. Instances of the metadata interfaces + can be obtained from the SessionFactory. + + Cat fritz =3D ......; ClassMetadata catMeta =3D sessionfactory.getClassMetadata(Cat.class); = Object[] propertyValues =3D catMeta.getPropertyValues(fritz); @@ -1280,13 +1194,10 @@ = // get a Map of all properties which are not collections or associations Map namedValues =3D new HashMap(); -for ( int i=3D0; i - = -
- +} +
- --===============8526693972957753615==--