From hibernate-commits at lists.jboss.org Wed Feb 7 17:08:02 2007 Content-Type: multipart/mixed; boundary="===============2534708352217804784==" MIME-Version: 1.0 From: hibernate-commits at lists.jboss.org To: hibernate-commits at lists.jboss.org Subject: [hibernate-commits] Hibernate SVN: r11162 - in branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en: modules and 1 other directory. Date: Wed, 07 Feb 2007 17:08:01 -0500 Message-ID: --===============2534708352217804784== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: epbernard Date: 2007-02-07 17:08:01 -0500 (Wed, 07 Feb 2007) New Revision: 11162 Removed: branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/lucene= .xml branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/valida= tor.xml Modified: branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/master.xml branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/entity= .xml branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/setup.= xml Log: new Annotations documentation Modified: branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/master.= 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 --- branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/master.xml 20= 07-02-07 07:43:17 UTC (rev 11161) +++ branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/master.xml 20= 07-02-07 22:08:01 UTC (rev 11162) @@ -4,8 +4,7 @@ - - + ]> @@ -13,7 +12,7 @@ = Reference Guide = - 3.2.1.GA + 3.2.2.GA = @@ -63,8 +62,8 @@ informations. = If you are moving from previous Hibernate Annotations versions, - please have a look at http://www.hibernate.org/371.html for= a - migration guide. + please have a look at Java + Persistence migration guide. = &setup; @@ -73,7 +72,6 @@ = &xml-overriding; = - &validator; + &additionalmodules; = - &lucene; \ No newline at end of file Modified: branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules= /entity.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 --- branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/entit= y.xml 2007-02-07 07:43:17 UTC (rev 11161) +++ branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/entit= y.xml 2007-02-07 22:08:01 UTC (rev 11162) @@ -1,12 +1,12 @@ - + Entity Beans = - + Intro = - This section covers EJB 3.0 (aka JPA) entity annotations and - Hibernate-specific extensions. + This section covers EJB 3.0 (aka Java Persistence) entity + annotations and Hibernate-specific extensions. = @@ -1203,11 +1203,11 @@ annotation takes into parameter a list of comma separated (target entity) properties to order the collection by (eg firstname asc, age desc), if the string is empty, the collection wi= ll - be ordered by id. For true indexed - collections, please refer to the . - EJB3 allows you to map Maps using as a key one of the target ent= ity - property using @MapKey(name=3D"myProperty") - (myProperty is a property name in the target entity). When using + be ordered by id. For true indexed collections, please refer to = the + . EJB3 allows you to map Maps= using + as a key one of the target entity property using + @MapKey(name=3D"myProperty") (myProperty is a + property name in the target entity). When using @MapKey (without property name), the target entity primary key is used. The map key uses the same column as = the property pointed out: there is no additional column defined to h= old Deleted: branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/= lucene.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 --- branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/lucen= e.xml 2007-02-07 07:43:17 UTC (rev 11161) +++ branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/lucen= e.xml 2007-02-07 22:08:01 UTC (rev 11162) @@ -1,670 +0,0 @@ - - - Hibernate Search: Apache <trademark>Lucene</trademark> - Integration - - Apache Lucene is a - high-performance Java search engine library available at the Apache Soft= ware - Foundation. Hibernate Annotations includes a package of annotations that - allows you to mark any domain model object as indexable and have Hiberna= te - maintain a Lucene index of any instances persisted via Hibernate. Apache - Lucene is also integrated with the Hibernate query facility. - - Hibernate Search is a work in progress and new features are cookin= g in - this area. So expect some compatibility changes in subsequent - versions. - -
- Architecture - - Hibernate Search is made of an indexing engine and an index sear= ch - engine. Both are backed by Apache Lucene. - - When an entity is inserted, updated or removed to/from the datab= ase, - Hibernate Search will keep track of this ev= ent - (through the Hibernate event system) and schedule an index update. When - out of transaction, the update is executed right after the actual data= base - operation. It is however recommended, for both your database and Hiber= nate - Search, to execute your operation in a transaction (whether JDBC or JT= A). - When in a transaction, the index update is schedule for the transaction - commit (and discarded in case of transaction rollback). You can think = of - this as the regular (infamous) autocommit vs transactional behavior. F= rom - a performance perspective, the in transaction mod= e is - recommended. All the index updates are handled for you without you hav= ing - to use the Apache Lucene APIs. - - To interact with Apache Lucene indexes, Hibernate Search has the - notion of DirectoryProvider. A directory provid= er - will manage a given Lucene Directory type. You = can - configure directory providers to adjust the directory target. - - Hibernate Search can also use a Lucene - index to search an entity and return a (list of) managed entity saving= you - from the tedious Object / Lucene Document mapping and low level Lucene - APIs. The application code use the unified - org.hibernate.Query API exactly the way a HQL or - native query would be done. -
- -
- Configuration - -
- Directory configuration - - Apache Lucene has a notion of Directory where the index is sto= red. - The Directory implementation can be customized but Lucene comes bund= led - with a file system and a full memory implementation. - Hibernate Search has the notion of - DirectoryProvider that handle the configuration a= nd - the initialization of the Lucene Directory. - - - List of built-in Directory Providers - - - - - Class - - description - - Properties - - - - - - org.hibernate.search.store.FSDirectoryProvider - - File system based directory. The directory used will = be - <indexBase>/<@Indexed.name> - - indexBase: Base directory - - - - org.hibernate.search.store.RAMDirectoryProvider - - Memory based directory, the directory will be uniquely - indentified by the @Indexed.name - element - - none - - - -
- - If the built-in directory providers does not fit your needs, y= ou - can write your own directory provider by implementing the - org.hibernate.store.DirectoryProvider - interface - - Each indexed entity is associated to a Lucene index (an index = can - be shared by several entities but this is not usually the case). You= can - configure the index through properties prefixed by - hibernate.search.indexname. - Default properties inherited to all indexes can be defined using the - prefix hibernate.search.default. - - To define the directory provider of a given index, you use the - hibernate.search.indexname.dire= ctory_provider - - hibernate.search.default.directory_provider org.hibe= rnate.search.store.FSDirectoryProvider -hibernate.search.default.indexBase=3D/usr/lucene/indexes - -hibernate.search.Rules.directory_provider org.hibernate.search.store.RAMDi= rectoryProvider - - - applied on - - @Indexed(name=3D"Status") -public class Status { ... } - -(a)Indexed(name=3D"Rules") -public class Rule { ... } - - will create a file system directory in - /usr/lucene/indexes/Status where the Status - entities will be indexed, and use an in memory directory named - Rules where Rule entities will be indexed. - - So you can easily defined common rules like the directory prov= ider - and base directory, and overide those default later on on a per index - basis. - - Writing your own DirectoryProvider, you= can - benefit this configuration mechanism too. -
- -
- Enabling automatic indexing - - Finally, we enable the SearchEventListener = for - the three Hibernate events that occur after changes are executed to = the - database. - - <hibernate-configuration> - ... - <event type=3D"post-update" = - <listener class=3D"org.hibernate.search.event.FullTextIndexEven= tListener"/> - </event> - <event type=3D"post-insert" = - <listener class=3D"org.hibernate.search.event.FullTextIndexEven= tListener"/> - </event> - <event type=3D"post-delete" = - <listener class=3D"org.hibernate.search.event.FullTextIndexEven= tListener"/> - </event> -</hibernate-configuration> -
-
- -
- Mapping entities to the index structure - - All the metadata information related to indexed entities is - described through some Java annotations. There is no need for xml mapp= ing - files nor a list of indexed entities. The list is discovered at startup - time scanning the Hibernate mapped entities. - - First, we must declare a persistent class as indexable. This is = done - by annotating the class with @Indexed (all entities= not - annotated with @Indexed will be ignored by the inde= xing - process): - - @Entity -@Indexed(index=3D"indexes/essays") -public class Essay { - ... -} - - The index attribute tells Hibernate what the - Lucene directory name is (usually a directory on your file system). If= you - wish to define a base directory for all Lucene indexes, you can use the - hibernate.search.default.indexBase property in your - configuration file. Each entity instance will be represented by a Luce= ne - Document inside the given index (aka - Directory). - - For each property (or attribute) of your entity, you have the - ability to describe how it will be indexed. The default (ie no annotat= ion) - means that the property is completly ignored by the indexing process. - @Field does declare a property as indexed. When - indexing an element to a Lucene document you can specify how it is - indexed: - - - - name: describe under which name, the prop= erty - should be stored in the Lucene Document. The default value is the - property name (following the JavaBeans convention) - - - - store: describe whether or not the proper= ty - is stored in the Lucene index. You can store the value - Store.YES (comsuming more space in the index), - store it in a compressed way Store.COMPRESS (th= is - does consume more CPU), or avoid any storage - Store.NO (this is the default value). When a - property is stored, you can retrieve it from the Lucene Document (= note - that this is not related to whether the element is indexed or - not). - - - - index: describe how the element is indexed (ie the process u= sed - to index the property and the type of information store). The - different values are Index.NO (no indexing, ie - cannot be found by a query), Index.TOKENIZED (u= se - an analyzer to process the property), - Index.UN_TOKENISED (no analyzer pre processing), - Index.NO_NORM (do not store the normalization - data). - - - - These attributes are part of the @Field - annotation. - - Whether or not you want to store the data depends on how you wis= h to - use the index query result. As of today, for a pure Hiber= nate - Search usage, storing is not necessary. Whether or not y= ou - want to tokenize a property or not depends on whether you wish to sear= ch - the element as is, or only normalized part of it. It make sense to - tokenize a text field, but it does not to do it for a date field (or a= n id - field). - - Finally, the id property of an entity is a special property used= by - Hibernate Search to ensure index unicity of= a - given entity. By design, an id has to be stored and must not be tokeni= zed. - To mark a property as index id, use the @DocumentId - annotation. - - @Entity -(a)Indexed(index=3D"indexes/essays") -public class Essay { - ... - - @Id - @DocumentId - public Long getId() { return id; } - = - @Field(name=3D"Abstract", index=3DIndex.TOKENI= ZED, store=3DStore.YES) - public String getSummary() { return summary; } - = - @Lob - @Field(index=3DIndex.TOKENIZED) - public String getText() { return text; } - = -} - - These annotations define an index with three fields: - id, Abstract and - text. Note that by default the field name is - decapitalized, following the JavaBean specification. - - Note: you must specify - @DocumentId on the identifier property of your enti= ty - class. - - Lucene has the notion of boost factor. It's= a - way to give more weigth to a field or to an indexed element over an ot= her - during the indexation process. You can use @Boost at - the field or the class level. - - @Entity -(a)Indexed(index=3D"indexes/essays") -@Boost(2) -public class Essay { - ... - - @Id - @DocumentId - public Long getId() { return id; } - = - @Field(name=3D"Abstract", index=3DIndex.TOKENIZED, store=3DStore.YES) - @Boost(2.5f) - public String getSummary() { return summary; } - = - @Lob - @Field(index=3DIndex.TOKENIZED) - public String getText() { return text; } - = -} - - In our example, Essay's probability to reach the top of the sear= ch - list will be multiplied by 2 and the summary field will be 2.5 more - important than the test field. Note that this explaination is actually - wrong, but it is simple and close enought to the reality. Please check= the - Lucene documentation or the excellent Lucene In - Action from Otis Gospodnetic and Erik Hatcher. - - The analyzer class used to index the elements is configurable - through the hibernate.search.analyzer property. If = none - defined, - org.apache.lucene.analysis.standard.StandardAnalyzer - is used as the default. -
- -
- Property/Field Bridge - - All field of a full text index in Lucene have to be represented = as - Strings. Ones Java properties have to be indexed in a String form. For - most of your properties, Hibernate Search d= oes - the translation job for you thanks to a built-in set of bridges. In so= me - cases, though you need a fine grain control over the translation - process. - -
- Built-in bridges - - Hibernate Search comes bundled with a set of - built-in bridges between a Java property type and its full text - representation. - - Null elements are not indexed (Lucene does = not - support null elements and it does not make much sense either) - - - - null - - - null elements are not indexed. Lucene does not support n= ull - elements and this does not make much sense either. - - - - - java.lang.String - - - String are indexed as is - - - - - short, Short, integer, Integer, long, Long, float, Float, - double, Double, BigInteger, BigDecimal - - - Numbers are converted in their String representation. No= te - that numbers cannot be compared by Lucene (ie used in ranged - queries) out of the box: they have to be padded - Using a Range query is debattable and has drawbacks,= an - alternative approach is to use a Filter query which will - filter the result query to the appropriate range. - - Hibernate Search will sup= port - a padding mechanism - - - - - - java.util.Date - - - Dates are stored as yyyyMMddHHmmssSSS in GMT time - (200611072203012 for Nov 7th of 2006 4:03PM and 12ms EST). You - shouldn't really bother with the internal format. What is - important is that when using a DateRange Query, you should know - that the dates have to be expressed in GMT time. - - Usually, storing the date up to the milisecond is not - necessary. @DateBridge defines the appropri= ate - resolution you are willing to store in the index - (@DateBridge(resolution=3DResolution.DAY)). - The date pattern will then be truncated accordingly. - - @Entity @Indexed = -public class Meeting { - @Field(index=3DIndex.UN_TOKENIZED) - @DateBridge(resolution=3DResolution.MINUTE) - private Date date; - ... -} - - - A Date whose resolution is lower than - MILLISECOND cannot be a - @DocumentId - - - - - - -
- -
- Custom Bridge - - It can happen that the built-in bridges of Hibernate Search do= es - not cover some of your property types, or that the String representa= tion - used is not what you expect. - -
- StringBridge - - The simpliest custom solution is to give Hibern= ate - Search an implementation of your expected - object to String bridge. To do so you need to - implements the - org.hibernate.search.bridge.StringBridge - interface - - /** - * Padding Integer bridge. - * All numbers will be padded with 0 to match 5 digits - * - * @author Emmanuel Bernard - */ -public class PaddedIntegerBridge implements String= Bridge { - - private int PADDING =3D 5; - - public String objectToString(Object object) { - String rawInteger =3D ( (Integer) object ).toString(); - if (rawInteger.length() > PADDING) throw new IllegalArgumentExc= eption( "Try to pad on a number too big" ); - StringBuilder paddedInteger =3D new StringBuilder( ); - for ( int padIndex =3D rawInteger.length() ; padIndex < PADDING= ; padIndex++ ) { - paddedInteger.append('0'); - } - return paddedInteger.append( rawInteger ).toString(); - } -} - - Then any property or field can use this bridge thanks to the - @FieldBridge annotation - - @FieldBridge(impl =3D Padd= edIntegerBridge.class) -private Integer length; - - Parameters can be passed to the Bridge implementation making= it - more flexible. The Bridge implementation implements a - ParameterizedBridge interface, and the - parameters are passed through the @FieldBridge - annotation. - - public class PaddedIntegerBridge implements String= Bridge, ParameterizedBridge { - - public static String PADDING_PROPERTY =3D "padding"; - private int padding =3D 5; //default - - public void setParameterValues(Map parameters)= { - Object padding =3D parameters.get( PADDING_PROPERTY ); - if (padding !=3D null) this.padding =3D (Integer) padding; - } - - public String objectToString(Object object) { - String rawInteger =3D ( (Integer) object ).toString(); - if (rawInteger.length() > padding) throw new IllegalArgumentExc= eption( "Try to pad on a number too big" ); - StringBuilder paddedInteger =3D new StringBuilder( ); - for ( int padIndex =3D rawInteger.length() ; padIndex < padding= ; padIndex++ ) { - paddedInteger.append('0'); - } - return paddedInteger.append( rawInteger ).toString(); - } -} - - -//property -(a)FieldBridge(impl =3D PaddedIntegerBridge.class, = - params =3D @Parameter(name=3D"padding", va= lue=3D"10") ) -private Integer length; - - The ParameterizedBridge interface can= be - implemented by StringBridge, - TwoWayStringBridge, - FieldBridge implementations (see - bellow). - - If you expect to use your bridge implementation on for an id - property (ie annotated with @DocumentId), you n= eed - to use a slightly extended version of StringBridge - named TwoWayStringBridge. Hibernate - Search needs to read the string representation of the - identifier and generate the object out of it. There is not differe= nce - in the way the @FieldBridge annotation is - used. - - public class PaddedIntegerBridge implements TwoWay= StringBridge, ParameterizedBridge { - - public static String PADDING_PROPERTY =3D "padding"; - private int padding =3D 5; //default - - public void setParameterValues(Map parameters) { - Object padding =3D parameters.get( PADDING_PROPERTY ); - if (padding !=3D null) this.padding =3D (Integer) padding; - } - - public String objectToString(Object object) { - String rawInteger =3D ( (Integer) object ).toString(); - if (rawInteger.length() > padding) throw new IllegalArgumentExc= eption( "Try to pad on a number too big" ); - StringBuilder paddedInteger =3D new StringBuilder( ); - for ( int padIndex =3D rawInteger.length() ; padIndex < padding= ; padIndex++ ) { - paddedInteger.append('0'); - } - return paddedInteger.append( rawInteger ).toString(); - } - - public Object stringToObject(String stringValu= e) { - return new Integer(stringValue); - } -} - - -//id property -(a)DocumentId -(a)FieldBridge(impl =3D PaddedIntegerBridge.class, - params =3D @Parameter(name=3D"padding", value=3D"10") ) -private Integer id; - - It is critically important for the two-way process to be - idempotent (ie object =3D stringToObject( objectToString( object )= ) - ). -
- -
- FieldBridge - - Some usecase requires more than a simple object to string - translation when mapping a property to a Lucene index. To give you - most of the flexibility you can also implement a bridge as a - FieldBridge. This interface give you a prop= erty - value and let you map it the way you want in your Lucene - Document.This interface is very similar in = its - concept to the Hibernate - UserType. - - You can for example store a given property in two different - document fields - - /** - * Store the date in 3 different field year, month, day - * to ease Range Query per year, month or day - * (eg get all the elements of december for the last 5 years) - * - * @author Emmanuel Bernard - */ -public class DateSplitBridge implements FieldBridge { - private final static TimeZone GMT =3D TimeZone.getTimeZone("GMT"); - - public void set(String name, Object value, Doc= ument document, Field.Store store, Field.Index index, Float boost) { - Date date =3D (Date) value; - Calendar cal =3D GregorianCalendar.getInstance( GMT ); - cal.setTime( date ); - int year =3D cal.get( Calendar.YEAR ); - int month =3D cal.get( Calendar.MONTH ) + 1; - int day =3D cal.get( Calendar.DAY_OF_MONTH ); - //set year - Field field =3D new Field( name + ".year", String.valueOf(year), s= tore, index ); - if ( boost !=3D null ) field.setBoost( boost ); - document.add( field ); - //set month and pad it if needed - field =3D new Field( name + ".month", month < 10 ? "0" : "" + S= tring.valueOf(month), store, index ); - if ( boost !=3D null ) field.setBoost( boost ); - document.add( field ); - //set day and pad it if needed - field =3D new Field( name + ".day", day < 10 ? "0" : "" + Strin= g.valueOf(day), store, index ); - if ( boost !=3D null ) field.setBoost( boost ); - document.add( field ); - } -} - - -//property -@FieldBridge(impl =3D DateSplitBridge.class) -private Integer length; - - -
-
-
- -
- Querying - - The second most important capability of Hibernate - Search is the ability to execute a Lucene query and retr= ieve - entities managed by an Hibernate session, providing the power of Lucene - without living the Hibernate paradygm, and giving another dimension to= the - Hibernate classic search mechanisms (HQL, Criteria query, native SQL - query). - - To access the Hibernate Search queryi= ng - facilities, you have to use an Hibernate - FullTextSession. A SearchSession wrap an regular - org.hibernate.Session to provide query and inde= xing - capabilities. - - Session session =3D sessionFactory.openSession(); -... -FullTextSession fullTextSession =3D Search.createFullTextSession(session);= - - The search facility is built on native Lucene queries. - - org.apache.lucene.QueryParser parser =3D new QueryPars= er("title", new StopAnalyzer() ); - -org.hibernate.lucene.search.Query luceneQuery =3D parser.parse( "summary:F= estina Or brand:Seiko" ); -org.hibernate.Query fullTextQuery =3D fullTextSess= ion.createFullTextQuery( luceneQuery ); - -List result =3D fullTextQuery.list(); //return a list of managed objects - - The Hibernate query built on top of the Lucene query is a regular - org.hibernate.Query, you are is the same paradygm as - the other Hibernate query facilities (HQL, Native or Criteria). The - regular list(), uniqueResult(), - iterate() and scroll() can be - used. - - If you expect a reasonnable result number and expect to work on = all - of them, list() or - uniqueResult() are recommanded. - list() work best if the entity - batch-size is set up properly. Note that Hibernate - Seach has to process all Lucene Hits elements when using - list(), uniqueResult() - and iterate(). If you wish to minimize Lucene - document loading, scroll() is more appropriat= e, - Don't forget to close the ScrollableResults obj= ect - when you're done, since it keeps Lucene resources. - - An efficient way to work with queries is to use pagination. The - pagination API is exactly the one available in - org.hibernate.Query: - - org.hibernate.Query fullTextQu= ery =3D fullTextSession.createFullTextQuery( luceneQuery ); -fullTextQuery.setFirstResult(30); -fullTextQuery.setMaxResult(20); -fullTextQuery.list(); //will return a list of 20 elements starting from th= e 30th - - Only the relevant Lucene Documents are accessed. -
- -
- Indexing - - It is sometimes useful to index an object event if this object is - not inserted nor updated to the database. This is especially true when= you - want to build your index the first time. You can achieve that goal usi= ng - the FullTextSession. - - FullTextSession fullTextSession =3D Search.createFullT= extSession(session); -Transaction tx =3D fullTextSession.beginTransaction(); -for (Customer customer : customers) { - fullTextSession.index(customer); -} -tx.commit(); //index are written at commit time - - For maximum efficiency, Hibernate Search batch index operations - which and execute them at commit time (Note: you don't need to use - org.hibernate.Transaction in a JTA - environment). -
-
\ No newline at end of file Modified: branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules= /setup.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 --- branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/setup= .xml 2007-02-07 07:43:17 UTC (rev 11161) +++ branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/setup= .xml 2007-02-07 22:08:01 UTC (rev 11162) @@ -1,8 +1,8 @@ - + Setting up an annotations project</ti= tle> = - <section id=3D"setup-requirements"> + <section id=3D"setup-requirements" revision=3D"1"> <title>Requirements = @@ -12,27 +12,27 @@ = - This release requires Hibernate 3.2.0.GA and above. - Do not use this release of Hibernate Annotations with an older ver= sion - of Hibernate 3.x! + This release requires Hibernate 3.2.0.GA and above= . Do + not use this release of Hibernate Annotations with an older versio= n of + Hibernate 3.x! = - This release is known to work on Hibernate core 3.2.0.CR5, 3= .2.0.GA - and 3.2.1.GA + This release is known to work on Hibernate core 3.2.0.CR5 and + 3.2.x.GA = - Make sure you have JDK 5.0 installed. You can of course cont= inue - using XDoclet and get some of the benefits of annotation-based - metadata with older JDK versions. Note that this document only - describes JDK 5.0 annotations and you have to refer to the XDoclet - documentation for more information. + Make sure you have JDK 5.0 installed or above. You can of co= urse + continue using XDoclet and get some of the benefits of + annotation-based metadata with older JDK versions. Note that this + document only describes JDK 5.0 annotations and you have to refer = to + the XDoclet documentation for more information. = -
+
Configuration = First, set up your classpath (after you have created a new proje= ct @@ -43,17 +43,23 @@ = - Copy hibernate-annotations.jar and + Copy hibernate-annotations.jar, + lib/hibernate-comons-annotations.jar and lib/ejb3-persistence.jar from the Hibernate Annotations distribution to your classpath as well. = - - To use the , add the lucene jar - file. - = + If you wish to use Hibernate Validator (TODO make a link to HV d= oc), + download it from the Hibernate website and add + hibernate-validator.jar in your classpath. + + If you wish to use Hibernate Search (TODO make a link to HSearch + doc), download it from the Hibernate website and add + hibernate-search.jar and + lucene-core-x.y.z.jar in your classpath. + We also recommend a small wrapper class to startup Hibernate in a static initializer block, known as HibernateUtil. You might have seen this class in various forms in other areas of the Deleted: branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/= validator.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 --- branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/valid= ator.xml 2007-02-07 07:43:17 UTC (rev 11161) +++ branches/HAN_SPLIT/HibernateExt/metadata/doc/reference/en/modules/valid= ator.xml 2007-02-07 22:08:01 UTC (rev 11162) @@ -1,560 +0,0 @@ - - - Hibernate Validator - - Annotations are a very convenient and elegant way to specify invar= iant - constraints for a domain model. You can, for example, express that a - property should never be null, that the account balance should be strict= ly - positive, etc. These domain model constraints are declared in the bean - itself by annotating its properties. A validator can then read them and - check for constraint violations. The validation mechanism can be execute= d in - different layers in your application without having to duplicate any of - these rules (presentation layer, data access layer). Hibernate Validator= has - been designed for that purpose. - - Hibernate Validator works at two levels. First, it is able to check - in-memory instances of a class for constraint violations. Second, it can - apply the constraints to the Hibernate metamodel and incorporate them in= to - the generated database schema. - - Each constraint annotation is associated to a validator implementa= tion - responsible for checking the constraint on the entity instance. A valida= tor - can also (optionally) apply the constraint to the Hibernate metamodel, - allowing Hibernate to generate DDL that expresses the constraint. With t= he - appropriate event listener, you can execute the checking operation on - inserts and updates done by Hibernate. Hibernate Validator is not limite= d to - use with Hibernate. You can easily use it anywhere in your - application. - - When checking instances at runtime, Hibernate Validator returns - information about constraint violations in an array of - InvalidValues. Among other information, the - InvalidValue contains an error description message - that can embed the parameter values bundle with the annotation (eg. leng= th - limit), and message strings that may be externalized to a - ResourceBundle. - - - Constraints - - - What is a constraint? - - A constraint is represented by an annotation. A constraint usu= ally - has some attributes used to parameterize the constraints limits. The - constraint apply to the annotated element. - - - - Built in constraints - - Hibernate Validator comes with some built-in constraints, which - covers most basic data checks. As we'll see later, you're not limite= d to - them, you can in a minute write your own constraints. - - - Built-in constraints - - - - - - - Annotation - - Apply on - - Runtime checking - - Hibernate Metadata impact - - - - - - @Length(min=3D, max=3D) - - property (String) - - check if the string length match the range - - Column length will be set to max - - - - @Max(value=3D) - - property (numeric or string representation of a - numeric) - - check if the value is less than or equals to max - - Add a check constraint on the column - - - - @Min(value=3D) - - property (numeric or string representation of a - numeric) - - check if the value is more than or equals to min - - Add a check constraint on the column - - - - @NotNull - - property - - check if the value is not null - - Column(s) are not null - - - - @NotEmpty - - property - - check if the string is not null nor empty. Check if t= he - connection is not null nor empty - - Column(s) are not null (for String) - - - - @Past - - property (date or calendar) - - check if the date is in the past - - Add a check constraint on the column - - - - @Future - - property (date or calendar) - - check if the date is in the future - - none - - - - @Pattern(regex=3D"regexp", flag=3D) - - property (string) - - check if the property match the regular expression gi= ven - a match flag (see java.util.regex.Pattern - ) - - none - - - - @Range(min=3D, max=3D) - - property (numeric or string representation of a - numeric) - - check if the value is between min and max - (included) - - Add a check constraint on the column - - - - @Size(min=3D, max=3D) - - property (array, collection, map) - - check if the element size is between min and max - (included) - - none - - - - @AssertFalse - - property - - check that the method evaluates to false (useful for - constraints expressed in code rather than annotations) - - none - - - - @AssertTrue - - property - - check that the method evaluates to true (useful for - constraints expressed in code rather than annotations) - - none - - - - @Valid - - property (object) - - perform validation recursively on the associated obje= ct. - If the object is a Collection or an array, the elements are - validated recursively. If the object is a Map, the value - elements are validated recursively. - - none - - - - @Email - - property (String) - - check whether the string is conform to the email addr= ess - specification - - none - - - -
-
- - - Error messages - - Hibernate Validator comes with a default set of error messages - translated in about ten languages (if yours is not part of it, please - sent us a patch). You can override those messages by creating a - ValidatorMessages.properties or - (ValidatorMessages_loc.properties) and override= the - needed keys. You can even add your own additional set of messages wh= ile - writing your validator annotations. If Hibernate Validator cannot - resolve a key from your resourceBundle nor from ValidatorMessage, it - falls back to the default built-in values. - - Alternatively you can provide a - ResourceBundle while checking programmatically - the validation rules on a bean or if you want a completly different - interpolation mechanism, you can provide an implementation of - org.hibernate.validator.MessageInterpolator (check - the JavaDoc for more informations). - - - - Writing your own constraints - - Extending the set of built-in constraints is extremely easy. A= ny - constraint consists of two pieces: the constraint - descriptor (the annotation) and the constraint - validator (the implementation class). Here is a - simple user-defined descriptor: - - @ValidatorClass(CapitalizedValidator.class) -(a)Target(METHOD) = -(a)Retention(RUNTIME) -(a)Documented -public @interface Capitalized { - CapitalizeType type() default Capitalize.FIRST; - String message() default "has incorrect capitalization"; -} - - type is a parameter describing how the prop= erty - should to be capitalized. This is a user parameter fully dependant on - the annotation business. - - message is the default string used to descr= ibe - the constraint violation and is mandatory. You can hard code the str= ing - or you can externalize part/all of it through the Java ResourceBundle - mechanism. Parameters values are going to be injected inside the mes= sage - when the {parameter} string is found (in our exam= ple - Capitalization is not {type} would generate - Capitalization is not FIRST), externalizing the w= hole - string in ValidatorMessages.properties is - considered good practice. See . - - @ValidatorClass(CapitalizedValidator.class) -(a)Target(METHOD) = -(a)Retention(RUNTIME) -(a)Documented -public @interface Capitalized { - CapitalizeType type() default Capitalize.FIRST; - String message() default "{validator.capitalized}"; -} - -... -#in ValidatorMessages.properties -validator.capitalized=3DCapitalization is not {type} - - As you can see the {} notation is recursive. - - To link a descriptor to its validator implementation, we use t= he - @ValidatorClass meta-annotation. The validator cl= ass - parameter must name a class which implements - Validator<ConstraintAnnotation>. - - We now have to implement the validator (ie. the rule checking - implementation). A validation implementation can check the value of = the - a property (by implementing PropertyConstraint) - and/or can modify the hibernate mapping metadata to express the - constraint at the database level (by implementing - PersistentClassConstraint). - - public class CapitalizedValidator = - implements Validator<Capitalized>, PropertyConstraint { - private CapitalizeType type; - - //part of the Validator<Annotation> contract, = - //allows to get and use the annotation values - public void initialize(Capitalized parameters) { - type =3D parameters.type(); - } - - //part of the property constraint contract - public boolean isValid(Object value) { - if (value=3D=3Dnull) return true; - if ( !(value instanceof String) ) return false; - String string =3D (String) value; - if (type =3D=3D CapitalizeType.ALL) { - return string.equals( string.toUpperCase() ); - } - else { - String first =3D string.substring(0,1); - return first.equals( first.toUpperCase(); - } - } -} - - The isValid() method should return false if= the - constraint has been violated. For more examples, refer to the built-= in - validator implementations. - - We only have seen property level validation, but you can write= a - Bean level validation annotation. Instead of receiving the return - instance of a property, the bean itself will be passed to the valida= tor. - To activate the validation checking, just annotated the bean itself - instead. A small sample can be found in the unit test suite. - - - - Annotating your domain model - - Since you are already familiar with annotations now, the syntax - should be very familiar. - - public class Address { - private String line1; - private String line2; - private String zip; - private String state; - private String country; - private long id; - = - // a not null string of 20 characters maximum - @Length(max=3D20) = - @NotNull - public String getCountry() { - return country; - } - = - // a non null string - @NotNull - public String getLine1() { - return line1; - } - - //no constraint = - public String getLine2() { - return line2; - } - = - // a not null string of 3 characters maximum - @Length(max=3D3) @NotNull - public String getState() { - return state; - } - - // a not null numeric string of 5 characters maximum - // if the string is longer, the message will = - //be searched in the resource bundle at key 'long' - @Length(max=3D5, message=3D"{long}") - @Pattern(regex=3D"[0-9]+") - @NotNull - public String getZip() { - return zip; - } - = - // should always be true - @AssertTrue - public boolean isValid() { - return true; - } - - // a numeric between 1 and 2000 - @Id @Min(1) - @Range(max=3D2000) - public long getId() { - return id; - } -} - - While the example only shows public property validation, you c= an - also annotate fields of any kind of visibility. - - @MyBeanConstraint(max=3D45) -public class Dog { - @AssertTrue private boolean isMale; - @NotNull protected String getName() { ... }; - ... -} - - You can also annotate interfaces. Hibernate Validator will che= ck - all superclasses and interfaces extended or implemented by a given b= ean - to read the appropriate validator annotations. - - public interface Named { - @NotNull String getName(); - ... -} - -public class Dog implements Named { - - @AssertTrue private boolean isMale; - - public String getName() { ... }; - -} - - The name property will be checked for nullity when the Dog bea= n is - validated. - -
- - - Using the Validator framework - - Hibernate Validator is intended to be used to implement - multi-layered data validation, where we express constraints in one pla= ce - (the annotated domain model) and apply them at various different layer= s of - the application. - - - Database schema-level validation - - Out of the box, Hibernate Annotations will translate the - constraints you have defined for your entities into mapping metadata. - For example, if a property of your entity is annotated - @NotNull, its columns will be declared as - not null in the DDL schema generated by - Hibernate. - - - - Hibernate event-based validation - - Hibernate Validator has two built-in Hibernate event listeners. - Whenever a PreInsertEvent or - PreUpdateEvent occurs, the listeners will verify = all - constraints of the entity instance and throw an exception if any - constraint is violated. Basically, objects will be checked before any - inserts and before any updates made by Hibernate. This is the most - convenient and the easiest way to activate the validation process. On - constraint violation, the event will raise a runtime - InvalidStateException which contains an array= of - InvalidValues describing each failure. - - <hibernate-configuration> - ... - <event type=3D"pre-update"> - <listener = - class=3D"org.hibernate.validator.event.ValidatePreUpdateEventLis= tener"/> - </event> - <event type=3D"pre-insert"> - <listener = - class=3D"org.hibernate.validator.event.ValidatePreInsertEventLis= tener"/> - </event> -</hibernate-configuration> - - - When using Hibernate Entity Manager, the Validation framew= ork - is activated out of the box. If the beans are not annotated with - validation annotations, there is no performance cost. - - - - - Application-level validation - - Hibernate Validator can be applied anywhere in your application - code. - - ClassValidator personValidator =3D new ClassValidato= r( Person.class ); -ClassValidator addressValidator =3D new ClassValidator( Address.class, Res= ourceBundle.getBundle("messages", Locale.ENGLISH) ); - -InvalidValue[] validationMessages =3D addressValidator.getInvalidValues(ad= dress); - - The first two lines prepare the Hibernate Validator for class - checking. The first one relies upon the error messages embedded in - Hibernate Validator (see ), the second one uses a - resource bundle for these messages. It is considered a good practice= to - execute these lines once and cache the validator instances. - - The third line actually validates the Address - instance and returns an array of InvalidValues. Y= our - application logic will then be able to react to the failure. - - You can also check a particular property instead of the whole - bean. This might be useful for property per property user - interaction - - ClassValidator addressValidator =3D new ClassValidat= or( Address.class, ResourceBundle.getBundle("messages", Locale.ENGLISH) ); - -//only get city property invalid values -InvalidValue[] validationMessages =3D addressValidator.getInvalidValues(ad= dress, "city"); - -//only get potential city property invalid values -InvalidValue[] validationMessages =3D addressValidator.getPotentialInvalid= Values("city", "Paris") - - - - Validation informations - - As a validation information carrier, hibernate provide an arra= y of - InvalidValue. Each - InvalidValue has a buch of methods describing the - individual issues. - - getBeanClass() retrieves the failing = bean - type - - getBean()retrieves the failing instan= ce - (if any ie not when using - getPotentianInvalidValues()) - - getValue() retrieves the failing - value - - getMessage() retrieves the proper - internationalized error message - - getRootBean() retrieves the root bean - instance generating the issue (useful in conjunction with - @Valid), is null if getPotentianInvalidValues() is - used. - - getPropertyPath() retrieves the dotted path= of - the failing property starting from the root bean - - -
\ No newline at end of file --===============2534708352217804784==--