Hibernate SVN: r15348 - in search/trunk/src/test/org/hibernate/search/test: query and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2008-10-14 14:54:24 -0400 (Tue, 14 Oct 2008)
New Revision: 15348
Modified:
search/trunk/src/test/org/hibernate/search/test/AlternateDocument.java
search/trunk/src/test/org/hibernate/search/test/Document.java
search/trunk/src/test/org/hibernate/search/test/query/Book.java
Log:
Removed some obsolete annotations.
Modified: search/trunk/src/test/org/hibernate/search/test/AlternateDocument.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/AlternateDocument.java 2008-10-14 18:53:41 UTC (rev 15347)
+++ search/trunk/src/test/org/hibernate/search/test/AlternateDocument.java 2008-10-14 18:54:24 UTC (rev 15348)
@@ -36,7 +36,6 @@
}
@Id
- //@Keyword(id = true)
@DocumentId()
public Long getId() {
return id;
@@ -46,7 +45,6 @@
this.id = id;
}
- //@Text
@Field( name = "alt_title", store = Store.YES, index = Index.TOKENIZED )
@Boost(2)
public String getTitle() {
@@ -57,7 +55,6 @@
this.title = title;
}
- //@Unstored(name = "Abstract")
@Field( name="Abstract", store = Store.NO, index = Index.TOKENIZED )
public String getSummary() {
return summary;
@@ -68,7 +65,6 @@
}
@Lob
- //@Unstored
@Field( store = Store.NO, index = Index.TOKENIZED )
public String getText() {
return text;
Modified: search/trunk/src/test/org/hibernate/search/test/Document.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/Document.java 2008-10-14 18:53:41 UTC (rev 15347)
+++ search/trunk/src/test/org/hibernate/search/test/Document.java 2008-10-14 18:54:24 UTC (rev 15348)
@@ -33,7 +33,6 @@
@Id
@GeneratedValue
- //@Keyword(id = true)
@DocumentId
public Long getId() {
return id;
@@ -43,7 +42,6 @@
this.id = id;
}
- //@Text
@Field( store = Store.YES, index = Index.TOKENIZED )
@Boost(2)
public String getTitle() {
@@ -54,7 +52,6 @@
this.title = title;
}
- //@Unstored(name = "Abstract")
@Field( name="Abstract", store = Store.NO, index = Index.TOKENIZED )
public String getSummary() {
return summary;
@@ -65,7 +62,6 @@
}
@Lob
- //@Unstored
@Field( store = Store.NO, index = Index.TOKENIZED )
public String getText() {
return text;
Modified: search/trunk/src/test/org/hibernate/search/test/query/Book.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/query/Book.java 2008-10-14 18:53:41 UTC (rev 15347)
+++ search/trunk/src/test/org/hibernate/search/test/query/Book.java 2008-10-14 18:54:24 UTC (rev 15348)
@@ -61,7 +61,6 @@
this.body = body;
}
- //@Unstored
@Field(index=Index.TOKENIZED, store=Store.NO)
public String getBody() {
return body;
15 years, 7 months
Hibernate SVN: r15347 - in search/trunk/doc: quickstart and 18 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2008-10-14 14:53:41 -0400 (Tue, 14 Oct 2008)
New Revision: 15347
Added:
search/trunk/doc/quickstart/
search/trunk/doc/quickstart/pom.xml
search/trunk/doc/quickstart/src/
search/trunk/doc/quickstart/src/main/
search/trunk/doc/quickstart/src/main/resources/
search/trunk/doc/quickstart/src/main/resources/META-INF/
search/trunk/doc/quickstart/src/main/resources/META-INF/maven/
search/trunk/doc/quickstart/src/main/resources/META-INF/maven/archetype.xml
search/trunk/doc/quickstart/src/main/resources/archetype-resources/
search/trunk/doc/quickstart/src/main/resources/archetype-resources/pom.xml
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/java/
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/java/example/
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/java/example/Author.java
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/java/example/Book.java
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/resources/
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/resources/META-INF/
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/resources/META-INF/persistence.xml
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/resources/log4j.properties
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/test/
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/test/java/
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/test/java/java/
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/test/java/java/example/
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/test/java/java/example/IndexAndSearchTest.java
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/test/resources/
search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/test/resources/import.sql
Modified:
search/trunk/doc/reference/en/modules/getting-started.xml
Log:
HSEARCH-231
Added a quickstart maven archetype and mentioned it in reference guide.
Property changes on: search/trunk/doc/quickstart
___________________________________________________________________
Name: svn:ignore
+ target
Added: search/trunk/doc/quickstart/pom.xml
===================================================================
--- search/trunk/doc/quickstart/pom.xml (rev 0)
+++ search/trunk/doc/quickstart/pom.xml 2008-10-14 18:53:41 UTC (rev 15347)
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-search-quickstart</artifactId>
+ <packaging>jar</packaging>
+ <version>3.1.0.Beta2</version>
+</project>
Added: search/trunk/doc/quickstart/src/main/resources/META-INF/maven/archetype.xml
===================================================================
--- search/trunk/doc/quickstart/src/main/resources/META-INF/maven/archetype.xml (rev 0)
+++ search/trunk/doc/quickstart/src/main/resources/META-INF/maven/archetype.xml 2008-10-14 18:53:41 UTC (rev 15347)
@@ -0,0 +1,17 @@
+<archetype>
+ <id>hibernate-search-quickstart</id>
+ <sources>
+ <source>src/main/java/example/Book.java</source>
+ <source>src/main/java/example/Author.java</source>
+ </sources>
+ <resources>
+ <resource>src/main/resources/log4j.properties</resource>
+ <resource>src/main/resources/META-INF/persistence.xml</resource>
+ </resources>
+ <testSources>
+ <source>src/test/java/java/example/IndexAndSearchTest.java</source>
+ </testSources>
+ <testResources>
+ <resource>src/test/resources/import.sql</resource>
+ </testResources>
+</archetype>
Added: search/trunk/doc/quickstart/src/main/resources/archetype-resources/pom.xml
===================================================================
--- search/trunk/doc/quickstart/src/main/resources/archetype-resources/pom.xml (rev 0)
+++ search/trunk/doc/quickstart/src/main/resources/archetype-resources/pom.xml 2008-10-14 18:53:41 UTC (rev 15347)
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>${groupId}</groupId>
+ <artifactId>${artifactId}</artifactId>
+ <packaging>jar</packaging>
+ <version>${version}</version>
+ <name>A custom project</name>
+ <url>http://www.myorganization.org</url>
+ <dependencies>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-search</artifactId>
+ <version>3.1.0.Beta2</version>
+ </dependency>
+ <dependency>
+ <groupId>cglib</groupId>
+ <artifactId>cglib</artifactId>
+ <version>2.1_3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-annotations</artifactId>
+ <version>3.4.0.CR1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-entitymanager</artifactId>
+ <version>3.4.0.CR1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.solr</groupId>
+ <artifactId>solr-common</artifactId>
+ <version>1.3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.solr</groupId>
+ <artifactId>solr-core</artifactId>
+ <version>1.3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.solr</groupId>
+ <artifactId>solr-lucene-snowball</artifactId>
+ <version>1.3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.4.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.4.2</version>
+ </dependency>
+ <dependency>
+ <groupId>hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <version>1.8.0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.4</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
Added: search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/java/example/Author.java
===================================================================
--- search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/java/example/Author.java (rev 0)
+++ search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/java/example/Author.java 2008-10-14 18:53:41 UTC (rev 15347)
@@ -0,0 +1,35 @@
+package example;
+
+import org.hibernate.search.annotations.*;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/*
+ *
+ */
+@Entity
+public class Author {
+ @Id
+ @GeneratedValue
+ private Integer id;
+ private String name;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ @Field(index = Index.TOKENIZED, store = Store.YES)
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Added: search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/java/example/Book.java
===================================================================
--- search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/java/example/Book.java (rev 0)
+++ search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/java/example/Book.java 2008-10-14 18:53:41 UTC (rev 15347)
@@ -0,0 +1,88 @@
+package example;
+
+import org.hibernate.search.annotations.*;
+import org.apache.solr.analysis.*;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import example.Author;
+
+/**
+ *
+ */
+@Entity
+@AnalyzerDef(name = "customanalyzer",
+ tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
+ filters = {
+ @TokenFilterDef(factory = LowerCaseFilterFactory.class),
+ @TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = {
+ @Parameter(name = "language", value = "English")
+ })
+ })
+@Indexed
+public class Book {
+
+ private Integer id;
+ private String title;
+ private String subtitle;
+ private Set<Author> authors = new HashSet<Author>();
+ private Date publicationDate;
+
+ @IndexedEmbedded
+ @ManyToMany
+ public Set<Author> getAuthors() {
+ return authors;
+ }
+
+ public void setAuthors(Set<Author> authors) {
+ this.authors = authors;
+ }
+
+ public Book() {
+ }
+
+ @Field(index = Index.TOKENIZED, store = Store.YES)
+ @Analyzer(definition = "customanalyzer")
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ @Id
+ @DocumentId
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ @Field(index = Index.TOKENIZED, store = Store.NO)
+ @Analyzer(definition = "customanalyzer")
+ public String getSubtitle() {
+ return subtitle;
+ }
+
+ public void setSubtitle(String subtitle) {
+ this.subtitle = subtitle;
+ }
+
+ @Field(index = Index.UN_TOKENIZED, store = Store.YES)
+ @DateBridge(resolution = Resolution.DAY)
+ public Date getPublicationDate() {
+ return publicationDate;
+ }
+
+ public void setPublicationDate(Date publicationDate) {
+ this.publicationDate = publicationDate;
+ }
+}
Added: search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/resources/META-INF/persistence.xml
===================================================================
--- search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/resources/META-INF/persistence.xml (rev 0)
+++ search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/resources/META-INF/persistence.xml 2008-10-14 18:53:41 UTC (rev 15347)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Persistence deployment descriptor for dev profile -->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+ version="1.0">
+
+ <persistence-unit name="hibernate-search-example">
+ <properties>
+
+ <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
+ <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
+ <property name="hibernate.connection.username" value="sa"/>
+ <property name="hibernate.connection.password" value=""/>
+ <property name="hibernate.connection.url" value="jdbc:hsqldb:."/>
+
+ <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
+
+ <property name="hibernate.search.default.indexBase"
+ value="target"/>
+
+ <!-- optional -->
+ <property name="hibernate.search.default.directory_provider"
+ value="org.hibernate.search.store.FSDirectoryProvider"/>
+ </properties>
+ </persistence-unit>
+</persistence>
Added: search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/resources/log4j.properties
===================================================================
--- search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/resources/log4j.properties (rev 0)
+++ search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/main/resources/log4j.properties 2008-10-14 18:53:41 UTC (rev 15347)
@@ -0,0 +1,31 @@
+### direct log messages to stdout ###
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+
+### direct messages to file hibernate.log ###
+log4j.appender.file=org.apache.log4j.FileAppender
+log4j.appender.file.File=hibernate.log
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+
+### direct messages to socket - chainsaw ###
+log4j.appender.socket=org.apache.log4j.net.SocketAppender
+log4j.appender.socket.remoteHost=localhost
+log4j.appender.socket.port=4560
+log4j.appender.socket.locationInfo=true
+
+### set log levels - for more verbose logging change 'info' to 'debug' ###
+
+log4j.rootLogger=info, stdout
+
+log4j.logger.org.hibernate=info
+
+### log just the SQL
+log4j.logger.org.hibernate.SQL=debug
+
+### log schema export/update ###
+log4j.logger.org.hibernate.tool.hbm2ddl=debug
+
+
Added: search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/test/java/java/example/IndexAndSearchTest.java
===================================================================
--- search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/test/java/java/example/IndexAndSearchTest.java (rev 0)
+++ search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/test/java/java/example/IndexAndSearchTest.java 2008-10-14 18:53:41 UTC (rev 15347)
@@ -0,0 +1,138 @@
+package example;
+
+import org.apache.lucene.queryParser.MultiFieldQueryParser;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.queryParser.QueryParser;
+import org.hibernate.Session;
+import org.hibernate.ejb.Ejb3Configuration;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.jpa.FullTextEntityManager;
+import org.hibernate.search.jpa.FullTextQuery;
+import org.junit.After;
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Query;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ */
+public class IndexAndSearchTest {
+
+ private EntityManagerFactory emf;
+
+ private EntityManager em;
+
+ private static Logger log = LoggerFactory.getLogger(IndexAndSearchTest.class);
+
+ @Before
+ public void setUp() {
+ initHibernate();
+ }
+
+ @After
+ public void tearDown() {
+ purge();
+ }
+
+ @Test
+ public void testIndexAndSearch() throws Exception {
+ List<Book> books = search("hibernate");
+ assertEquals("Should get empty list since nothing is indexed yet", 0, books.size());
+
+ index();
+
+ // search by title
+ books = search("hibernate");
+ assertEquals("Should find one book", 1, books.size());
+ assertEquals("Wrong title", "Java Persistence with Hibernate", books.get(0).getTitle());
+
+ // search author
+ books = search("\"Gavin King\"");
+ assertEquals("Should find one book", 1, books.size());
+ assertEquals("Wrong title", "Java Persistence with Hibernate", books.get(0).getTitle());
+ }
+
+ @Test
+ public void testStemming() throws Exception {
+
+ index();
+
+ List<Book> books = search("refactor");
+ assertEquals("Wrong title", "Refactoring: Improving the Design of Existing Code", books.get(0).getTitle());
+
+ books = search("refactors");
+ assertEquals("Wrong title", "Refactoring: Improving the Design of Existing Code", books.get(0).getTitle());
+
+ books = search("refactored");
+ assertEquals("Wrong title", "Refactoring: Improving the Design of Existing Code", books.get(0).getTitle());
+
+ books = search("refactoring");
+ assertEquals("Wrong title", "Refactoring: Improving the Design of Existing Code", books.get(0).getTitle());
+ }
+
+
+ private void initHibernate() {
+ Ejb3Configuration config = new Ejb3Configuration();
+ config.configure("hibernate-search-example", new HashMap());
+ emf = config.buildEntityManagerFactory();
+ em = emf.createEntityManager();
+ }
+
+ private void index() {
+ FullTextSession ftSession = org.hibernate.search.Search.getFullTextSession((Session) em.getDelegate());
+ List results = ftSession.createCriteria(Book.class).list();
+ for (Object obj : results) {
+ ftSession.index(obj);
+ }
+ }
+
+ private void purge() {
+ FullTextSession ftSession = org.hibernate.search.Search.getFullTextSession((Session) em.getDelegate());
+ ftSession.purgeAll(Book.class);
+ }
+
+ private List<Book> search(String searchQuery) throws ParseException {
+ Query query = searchQuery(searchQuery);
+
+ List<Book> books = query.getResultList();
+
+ for (Book b : books) {
+ log.info("Title: " + b.getTitle());
+ }
+ return books;
+ }
+
+ private Query searchQuery(String searchQuery) throws ParseException {
+
+ String[] bookFields = {"title", "subtitle", "authors.name", "publicationDate"};
+
+ //lucene part
+ Map<String, Float> boostPerField = new HashMap<String, Float>(4);
+ boostPerField.put(bookFields[0], (float) 4);
+ boostPerField.put(bookFields[1], (float) 3);
+ boostPerField.put(bookFields[2], (float) 4);
+ boostPerField.put(bookFields[3], (float) .5);
+
+ FullTextEntityManager ftEm = org.hibernate.search.jpa.Search.getFullTextEntityManager((EntityManager) em);
+
+ QueryParser parser = new MultiFieldQueryParser(bookFields, ftEm.getSearchFactory().getAnalyzer("customanalyzer"),
+ boostPerField);
+
+ org.apache.lucene.search.Query luceneQuery;
+ luceneQuery = parser.parse(searchQuery);
+
+ final FullTextQuery query = ftEm.createFullTextQuery(luceneQuery, Book.class);
+
+ return query;
+ }
+
+}
Added: search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/test/resources/import.sql
===================================================================
--- search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/test/resources/import.sql (rev 0)
+++ search/trunk/doc/quickstart/src/main/resources/archetype-resources/src/test/resources/import.sql 2008-10-14 18:53:41 UTC (rev 15347)
@@ -0,0 +1,293 @@
+INSERT INTO BOOK VALUES (0, '2007-06-26', '(Theory in Practice (O''Reilly))', 'Beautiful Code: Leading Programmers Explain How They Think');
+INSERT INTO AUTHOR VALUES (0, 'Greg Wilson');
+INSERT INTO BOOK_AUTHOR VALUES (0, 0);
+INSERT INTO AUTHOR VALUES (1, 'Andy Oram');
+INSERT INTO BOOK_AUTHOR VALUES (0, 1);
+INSERT INTO BOOK VALUES (1, '2007-06-01', '', 'Smart and Gets Things Done: Joel Spolsky''s Concise Guide to Finding the Best Technical Talent, Hardback: Joel Spolsky''s Concise Guide to Finding the Best Technical Talent');
+INSERT INTO AUTHOR VALUES (2, 'Joel Spolsky');
+INSERT INTO BOOK_AUTHOR VALUES (1, 2);
+INSERT INTO BOOK VALUES (2, '1998-11-30', '', 'R\344tsel der Kochkunst.');
+INSERT INTO AUTHOR VALUES (3, 'Herve This-Benckhard');
+INSERT INTO BOOK_AUTHOR VALUES (2, 3);
+INSERT INTO BOOK VALUES (3, '1995-03-14', '', 'Design patterns : elements of reusable object-oriented software');
+INSERT INTO AUTHOR VALUES (4, 'Richard Helm');
+INSERT INTO BOOK_AUTHOR VALUES (3, 4);
+INSERT INTO AUTHOR VALUES (5, 'Ralph Johnson');
+INSERT INTO BOOK_AUTHOR VALUES (3, 5);
+INSERT INTO AUTHOR VALUES (6, 'John Vlissides');
+INSERT INTO BOOK_AUTHOR VALUES (3, 6);
+INSERT INTO AUTHOR VALUES (7, 'Erich Gamma');
+INSERT INTO BOOK_AUTHOR VALUES (3, 7);
+INSERT INTO BOOK VALUES (4, '2001-04-01', '', 'Otherland IV: Sea of Silver Light');
+INSERT INTO AUTHOR VALUES (8, 'Tad Williams');
+INSERT INTO BOOK_AUTHOR VALUES (4, 8);
+INSERT INTO BOOK VALUES (5, '2008-01-01', '', 'Feuchtgebiete');
+INSERT INTO AUTHOR VALUES (9, 'Charlotte Roche');
+INSERT INTO BOOK_AUTHOR VALUES (5, 9);
+INSERT INTO BOOK VALUES (6, '2001-06-04', '', 'Kitchen Confidential');
+INSERT INTO AUTHOR VALUES (10, 'Anthony Bourdain');
+INSERT INTO BOOK_AUTHOR VALUES (6, 10);
+INSERT INTO BOOK VALUES (7, '1997-04-01', '', 'Langenscheidts Sprachf\374hrer, Schwedisch');
+INSERT INTO AUTHOR VALUES (11, 'Kerstin Jakten');
+INSERT INTO BOOK_AUTHOR VALUES (7, 11);
+INSERT INTO AUTHOR VALUES (12, 'Dirk Huth');
+INSERT INTO BOOK_AUTHOR VALUES (7, 12);
+INSERT INTO BOOK VALUES (8, '2000-03-30', '20th anniversary edition with a new preface by the author', 'Godel, Escher, Bach: An Eternal Golden Braid');
+INSERT INTO AUTHOR VALUES (13, 'Douglas R. Hofstadter');
+INSERT INTO BOOK_AUTHOR VALUES (8, 13);
+INSERT INTO BOOK VALUES (9, '1998-09-01', '', 'Konkrete Humanit\344t. Vorlesungen \374ber Verantwortung und Menschlichkeit.');
+INSERT INTO AUTHOR VALUES (14, 'Hans Lenk');
+INSERT INTO BOOK_AUTHOR VALUES (9, 14);
+INSERT INTO BOOK VALUES (10, '2005-03-01', '', 'From Naked Ape to Superspecies: Humanity and the Global Eco-crisis');
+INSERT INTO AUTHOR VALUES (15, 'Holly Dressel');
+INSERT INTO BOOK_AUTHOR VALUES (10, 15);
+INSERT INTO AUTHOR VALUES (16, 'David T. Suzuki');
+INSERT INTO BOOK_AUTHOR VALUES (10, 16);
+INSERT INTO BOOK VALUES (11, '2001-10-17', '', 'The Eureka Effect: The Art and Logic of Breakthrough Thinking');
+INSERT INTO AUTHOR VALUES (17, 'D Perkins');
+INSERT INTO BOOK_AUTHOR VALUES (11, 17);
+INSERT INTO BOOK VALUES (12, '2005-01-12', '', 'Lucene In Action');
+INSERT INTO AUTHOR VALUES (18, 'Otis Gospodnetic');
+INSERT INTO BOOK_AUTHOR VALUES (12, 18);
+INSERT INTO AUTHOR VALUES (19, 'Erik Hatcher');
+INSERT INTO BOOK_AUTHOR VALUES (12, 19);
+INSERT INTO BOOK VALUES (13, '1999-09-14', 'Yourdon Press computing series', 'Death March');
+INSERT INTO AUTHOR VALUES (20, 'Edward Yourdon');
+INSERT INTO BOOK_AUTHOR VALUES (13, 20);
+INSERT INTO BOOK VALUES (14, '2006-04-04', 'Pragmatic Programmers', 'Practices of an Agile Developer: Working in the Real World');
+INSERT INTO AUTHOR VALUES (21, 'Andy Hunt');
+INSERT INTO BOOK_AUTHOR VALUES (14, 21);
+INSERT INTO AUTHOR VALUES (22, 'Venkat Subramaniam');
+INSERT INTO BOOK_AUTHOR VALUES (14, 22);
+INSERT INTO BOOK VALUES (15, '2005-05-01', 'Barron''s Educational Series', '1001 Natural Wonders: You Must See Before You Die');
+INSERT INTO AUTHOR VALUES (23, 'Michael Bright');
+INSERT INTO BOOK_AUTHOR VALUES (15, 23);
+INSERT INTO BOOK VALUES (16, '1998-04-25', '', 'Guns, Germs and Steel: A short history of everybody for the last 13,000 years');
+INSERT INTO AUTHOR VALUES (24, 'Jared M. Diamond');
+INSERT INTO BOOK_AUTHOR VALUES (16, 24);
+INSERT INTO BOOK VALUES (17, '1986-04-01', '1st Series', 'Programmers at Work: Interviews');
+INSERT INTO AUTHOR VALUES (25, 'Susan Lammers');
+INSERT INTO BOOK_AUTHOR VALUES (17, 25);
+INSERT INTO BOOK VALUES (18, '1989-08-01', '', 'The Total Devotion Machine and Other Stories');
+INSERT INTO AUTHOR VALUES (26, 'Rosaleen Love');
+INSERT INTO BOOK_AUTHOR VALUES (18, 26);
+INSERT INTO BOOK VALUES (19, '2003-10-01', 'Lonely Planet Travel Guides', 'Catalunya and the Costa Brava');
+INSERT INTO AUTHOR VALUES (27, 'Damien Simonis');
+INSERT INTO BOOK_AUTHOR VALUES (19, 27);
+INSERT INTO BOOK VALUES (20, '2005-07-21', '', 'Java Puzzlers: Traps, Pitfalls, and Corner Cases');
+INSERT INTO AUTHOR VALUES (28, 'Neal Gafter');
+INSERT INTO BOOK_AUTHOR VALUES (20, 28);
+INSERT INTO AUTHOR VALUES (29, 'Joshua Bloch');
+INSERT INTO BOOK_AUTHOR VALUES (20, 29);
+INSERT INTO BOOK VALUES (21, '2008-01-01', '', 'Die Vermessung der Welt');
+INSERT INTO AUTHOR VALUES (30, 'Daniel Kehlmann');
+INSERT INTO BOOK_AUTHOR VALUES (21, 30);
+INSERT INTO BOOK VALUES (22, '1995-01-01', '', 'Logik f\374r Informatiker');
+INSERT INTO AUTHOR VALUES (31, 'Uwe Sch\366ning');
+INSERT INTO BOOK_AUTHOR VALUES (22, 31);
+INSERT INTO BOOK VALUES (23, '2007-04-17', '', 'The Children of Hurin');
+INSERT INTO AUTHOR VALUES (32, 'J.R.R. Tolkien');
+INSERT INTO BOOK_AUTHOR VALUES (23, 32);
+INSERT INTO BOOK VALUES (24, '1999-11-24', '', 'The Pragmatic Programmer');
+INSERT INTO AUTHOR VALUES (33, 'David Thomas');
+INSERT INTO BOOK_AUTHOR VALUES (24, 33);
+INSERT INTO AUTHOR VALUES (34, 'Andrew Hunt');
+INSERT INTO BOOK_AUTHOR VALUES (24, 34);
+INSERT INTO BOOK VALUES (25, '2003-06-19', 'Core', 'Core J2EE Patterns: Best Practices and Design Strategies');
+INSERT INTO AUTHOR VALUES (35, 'Dan Malks');
+INSERT INTO BOOK_AUTHOR VALUES (25, 35);
+INSERT INTO AUTHOR VALUES (36, 'John Crupi');
+INSERT INTO BOOK_AUTHOR VALUES (25, 36);
+INSERT INTO AUTHOR VALUES (37, 'Deepak Alur');
+INSERT INTO BOOK_AUTHOR VALUES (25, 37);
+INSERT INTO BOOK VALUES (26, '2004-01-01', '', 'Tala Svenska');
+INSERT INTO AUTHOR VALUES (38, 'Erbrou Olga Guttke');
+INSERT INTO BOOK_AUTHOR VALUES (26, 38);
+INSERT INTO BOOK VALUES (27, '2003-07-24', '', 'Extreme Programming Pocket Guide');
+INSERT INTO AUTHOR VALUES (39, 'Shane Warden');
+INSERT INTO BOOK_AUTHOR VALUES (27, 39);
+INSERT INTO BOOK VALUES (28, '2003-12-31', '', 'Schweden: Dem Kommissar auf der Spur.');
+INSERT INTO AUTHOR VALUES (40, 'Rainer Sens');
+INSERT INTO BOOK_AUTHOR VALUES (28, 40);
+INSERT INTO BOOK VALUES (29, '2002-01-01', '', 'Reader''s Digest 4 in 1 Condensed Books The Da Vinci Code, Up And Down In The Dales, The Return Of The Dancing Master, A Gathering Light');
+INSERT INTO AUTHOR VALUES (41, 'Henning Mankell');
+INSERT INTO BOOK_AUTHOR VALUES (29, 41);
+INSERT INTO AUTHOR VALUES (42, 'Jennifer Donnelly Dan Brown');
+INSERT INTO BOOK_AUTHOR VALUES (29, 42);
+INSERT INTO AUTHOR VALUES (43, 'Gervase Phinn');
+INSERT INTO BOOK_AUTHOR VALUES (29, 43);
+INSERT INTO BOOK VALUES (30, '2006-11-01', '', 'Cell.');
+INSERT INTO AUTHOR VALUES (44, 'Stephen King');
+INSERT INTO BOOK_AUTHOR VALUES (30, 44);
+INSERT INTO BOOK VALUES (31, '1999-01-01', '', 'Ratgeber nat\374rliche Gesundheit -Massage. Die heilende Kraft der Ber\374hrung. o.A.');
+INSERT INTO AUTHOR VALUES (45, 'Stewart Mitchell');
+INSERT INTO BOOK_AUTHOR VALUES (31, 45);
+INSERT INTO BOOK VALUES (32, '2006-01-01', '', 'Ich bin dann mal weg');
+INSERT INTO AUTHOR VALUES (46, 'Hape Kerkeling');
+INSERT INTO BOOK_AUTHOR VALUES (32, 46);
+INSERT INTO BOOK VALUES (33, '1990-01-01', '', 'Witzig, sehr witzig - Herr Pfarrer');
+INSERT INTO AUTHOR VALUES (47, 'Georg Gessner');
+INSERT INTO BOOK_AUTHOR VALUES (33, 47);
+INSERT INTO BOOK VALUES (34, '2007-07-12', '', 'Lisey''s Story');
+INSERT INTO AUTHOR VALUES (48, 'Stephen King');
+INSERT INTO BOOK_AUTHOR VALUES (34, 48);
+INSERT INTO BOOK VALUES (35, '1999-07-23', 'Object Technology Series', 'Refactoring: Improving the Design of Existing Code');
+INSERT INTO AUTHOR VALUES (49, 'Kent Beck');
+INSERT INTO BOOK_AUTHOR VALUES (35, 49);
+INSERT INTO AUTHOR VALUES (50, 'John Brant');
+INSERT INTO BOOK_AUTHOR VALUES (35, 50);
+INSERT INTO AUTHOR VALUES (51, 'William Opdyke');
+INSERT INTO BOOK_AUTHOR VALUES (35, 51);
+INSERT INTO AUTHOR VALUES (52, 'Don Roberts');
+INSERT INTO BOOK_AUTHOR VALUES (35, 52);
+INSERT INTO AUTHOR VALUES (53, 'Martin Fowler');
+INSERT INTO BOOK_AUTHOR VALUES (35, 53);
+INSERT INTO BOOK VALUES (36, '2003-08-31', '', 'Die Schatten der Globalisierung.');
+INSERT INTO AUTHOR VALUES (54, 'Joseph E. Stiglitz');
+INSERT INTO BOOK_AUTHOR VALUES (36, 54);
+INSERT INTO BOOK VALUES (38, '2006-06-09', 'Pragmatic Programmers', 'Rails Recipes');
+INSERT INTO AUTHOR VALUES (56, 'Chad Fowler');
+INSERT INTO BOOK_AUTHOR VALUES (38, 56);
+INSERT INTO BOOK VALUES (39, '1995-01-01', '', 'Theoretische Informatik, kurzgefa\337t');
+INSERT INTO AUTHOR VALUES (57, 'Uwe Sch\366ning');
+INSERT INTO BOOK_AUTHOR VALUES (39, 57);
+INSERT INTO BOOK VALUES (40, '2001-09-30', '', 'Ploetz. Der farbige Ploetz.');
+INSERT INTO AUTHOR VALUES (58, 'Horst Fischer-Uhlig');
+INSERT INTO BOOK_AUTHOR VALUES (40, 58);
+INSERT INTO BOOK VALUES (41, '2006-10-05', '', 'Freakonomics');
+INSERT INTO AUTHOR VALUES (59, 'Stephen J. Dubner');
+INSERT INTO BOOK_AUTHOR VALUES (41, 59);
+INSERT INTO AUTHOR VALUES (60, 'Steven D. Levitt');
+INSERT INTO BOOK_AUTHOR VALUES (41, 60);
+INSERT INTO BOOK VALUES (42, '2006-02-28', '', 'Das Auge des Leoparden');
+INSERT INTO AUTHOR VALUES (61, 'Henning Mankell');
+INSERT INTO BOOK_AUTHOR VALUES (42, 61);
+INSERT INTO BOOK VALUES (43, '2007-01-16', '', 'Dreaming in Code: Two Dozen Programmers, Three Years, 4,732 Bugs, and One Quest for Transcendent Software');
+INSERT INTO AUTHOR VALUES (62, 'Scott Rosenberg');
+INSERT INTO BOOK_AUTHOR VALUES (43, 62);
+INSERT INTO BOOK VALUES (44, '2007-07-02', '', 'Managing Humans: Biting and Humorous Tales of a Software Engineering Manager');
+INSERT INTO AUTHOR VALUES (63, 'M Lopp');
+INSERT INTO BOOK_AUTHOR VALUES (44, 63);
+INSERT INTO BOOK VALUES (45, '2002-01-01', '', 'Veronika Deschliesst Zu Sterben / Vernika Decides to Die');
+INSERT INTO AUTHOR VALUES (64, 'Paulo Coelho');
+INSERT INTO BOOK_AUTHOR VALUES (45, 64);
+INSERT INTO BOOK VALUES (46, '2002-05-07', '', 'One for My Baby');
+INSERT INTO AUTHOR VALUES (65, 'Tony Parsons');
+INSERT INTO BOOK_AUTHOR VALUES (46, 65);
+INSERT INTO BOOK VALUES (47, '2008-03-03', '', 'Adrenaline Junkies and Template Zombies: Understanding Patterns of Project Behavior');
+INSERT INTO AUTHOR VALUES (66, 'Peter Hruschka');
+INSERT INTO BOOK_AUTHOR VALUES (47, 66);
+INSERT INTO AUTHOR VALUES (67, 'Tim Lister');
+INSERT INTO BOOK_AUTHOR VALUES (47, 67);
+INSERT INTO AUTHOR VALUES (68, 'Steve McMenamin');
+INSERT INTO BOOK_AUTHOR VALUES (47, 68);
+INSERT INTO AUTHOR VALUES (69, 'James Robertson');
+INSERT INTO BOOK_AUTHOR VALUES (47, 69);
+INSERT INTO AUTHOR VALUES (70, 'Suzanne Robertson');
+INSERT INTO BOOK_AUTHOR VALUES (47, 70);
+INSERT INTO AUTHOR VALUES (71, 'Tom DeMarco');
+INSERT INTO BOOK_AUTHOR VALUES (47, 71);
+INSERT INTO BOOK VALUES (48, '1995-01-24', 'Computing', 'UNIX System Administration Handbook');
+INSERT INTO AUTHOR VALUES (72, 'Garth Snyder');
+INSERT INTO BOOK_AUTHOR VALUES (48, 72);
+INSERT INTO AUTHOR VALUES (73, 'Scott Seebass');
+INSERT INTO BOOK_AUTHOR VALUES (48, 73);
+INSERT INTO AUTHOR VALUES (74, 'Trent H. Hein');
+INSERT INTO BOOK_AUTHOR VALUES (48, 74);
+INSERT INTO AUTHOR VALUES (75, 'Evi Nemeth');
+INSERT INTO BOOK_AUTHOR VALUES (48, 75);
+INSERT INTO BOOK VALUES (49, '2001-08-06', '', 'Down Under');
+INSERT INTO AUTHOR VALUES (76, 'Bill Bryson');
+INSERT INTO BOOK_AUTHOR VALUES (49, 76);
+INSERT INTO BOOK VALUES (50, '2007-07-05', '', 'Heat');
+INSERT INTO AUTHOR VALUES (77, 'Bill Buford');
+INSERT INTO BOOK_AUTHOR VALUES (50, 77);
+INSERT INTO BOOK VALUES (51, '1998-01-03', '201 verbs series', '201 Swedish Verbs Fully Conjugated in All the Tenses');
+INSERT INTO AUTHOR VALUES (78, 'Richard P. Auletta');
+INSERT INTO BOOK_AUTHOR VALUES (51, 78);
+INSERT INTO BOOK VALUES (52, '2005-09-19', 'Pragmatic Programmers', 'My Job Went to India: 52 Ways to Save Your Job');
+INSERT INTO AUTHOR VALUES (79, 'Chad Fowler');
+INSERT INTO BOOK_AUTHOR VALUES (52, 79);
+INSERT INTO BOOK VALUES (53, '2005-10-01', '', 'Ajax in Action');
+INSERT INTO AUTHOR VALUES (80, 'Eric Pascarello');
+INSERT INTO BOOK_AUTHOR VALUES (53, 80);
+INSERT INTO AUTHOR VALUES (81, 'Darren James');
+INSERT INTO BOOK_AUTHOR VALUES (53, 81);
+INSERT INTO AUTHOR VALUES (82, 'Dave Crane');
+INSERT INTO BOOK_AUTHOR VALUES (53, 82);
+INSERT INTO BOOK VALUES (54, '2008-08-01', '', 'Duma Key');
+INSERT INTO AUTHOR VALUES (83, 'Stephen King');
+INSERT INTO BOOK_AUTHOR VALUES (54, 83);
+INSERT INTO BOOK VALUES (55, '1992-06-01', 'Nutshell Handbooks', 'Unix in a Nutshell: System V, Release 4');
+INSERT INTO AUTHOR VALUES (84, 'Daniel Gilly');
+INSERT INTO BOOK_AUTHOR VALUES (55, 84);
+INSERT INTO BOOK VALUES (56, '2006-03-16', '', 'Ghosts of Spain: Travels Through a Country''s Hidden Past');
+INSERT INTO AUTHOR VALUES (85, 'Giles Tremlett');
+INSERT INTO BOOK_AUTHOR VALUES (56, 85);
+INSERT INTO BOOK VALUES (57, '', '', 'In die Wildnis');
+INSERT INTO AUTHOR VALUES (86, 'Jon Krakauer');
+INSERT INTO BOOK_AUTHOR VALUES (57, 86);
+INSERT INTO BOOK VALUES (58, '2000-04-04', '', 'The Silicon Boys and Their Valley of Dreams');
+INSERT INTO AUTHOR VALUES (87, 'David A. Kaplan');
+INSERT INTO BOOK_AUTHOR VALUES (58, 87);
+INSERT INTO BOOK VALUES (59, '2006-04-06', '', 'Istanbul: Memories of a City');
+INSERT INTO AUTHOR VALUES (88, 'Orhan Pamuk');
+INSERT INTO BOOK_AUTHOR VALUES (59, 88);
+INSERT INTO BOOK VALUES (60, '2004-04-08', 'Advanced Tools and Techniques for Mysql Administrators', 'High Performance MySQL: Optimization, Backups, Replication, Load Balancing & More');
+INSERT INTO AUTHOR VALUES (89, 'Derek Balling');
+INSERT INTO BOOK_AUTHOR VALUES (60, 89);
+INSERT INTO AUTHOR VALUES (90, 'Jeremy Zawodny');
+INSERT INTO BOOK_AUTHOR VALUES (60, 90);
+INSERT INTO BOOK VALUES (61, '1996-01-01', '', 'LaTeX, 3 Bde., Bd.1, Einf\374hrung');
+INSERT INTO AUTHOR VALUES (91, 'Helmut Kopka');
+INSERT INTO BOOK_AUTHOR VALUES (61, 91);
+INSERT INTO BOOK VALUES (62, '2006-12-05', '', 'Java Persistence with Hibernate');
+INSERT INTO AUTHOR VALUES (92, 'Gavin King');
+INSERT INTO BOOK_AUTHOR VALUES (62, 92);
+INSERT INTO AUTHOR VALUES (93, 'Christian Bauer');
+INSERT INTO BOOK_AUTHOR VALUES (62, 93);
+INSERT INTO BOOK VALUES (63, '2006-12-14', 'Pragmatic Programmers', 'Agile Web Development with Rails');
+INSERT INTO AUTHOR VALUES (94, 'David Hansson ');
+INSERT INTO BOOK_AUTHOR VALUES (63, 94);
+INSERT INTO AUTHOR VALUES (95, 'Leon Breedt');
+INSERT INTO BOOK_AUTHOR VALUES (63, 95);
+INSERT INTO AUTHOR VALUES (96, 'Mike Clark');
+INSERT INTO BOOK_AUTHOR VALUES (63, 96);
+INSERT INTO AUTHOR VALUES (97, 'James Davidson');
+INSERT INTO BOOK_AUTHOR VALUES (63, 97);
+INSERT INTO AUTHOR VALUES (98, 'Justin Gehtland');
+INSERT INTO BOOK_AUTHOR VALUES (63, 98);
+INSERT INTO AUTHOR VALUES (99, 'Andreas Schwarz');
+INSERT INTO BOOK_AUTHOR VALUES (63, 99);
+INSERT INTO AUTHOR VALUES (100, 'Dave Thomas');
+INSERT INTO BOOK_AUTHOR VALUES (63, 100);
+INSERT INTO BOOK VALUES (64, '2001-10-01', 'Programmer to Programmer', 'Professional JavaScript');
+INSERT INTO AUTHOR VALUES (101, 'Paul Wilton');
+INSERT INTO BOOK_AUTHOR VALUES (64, 101);
+INSERT INTO AUTHOR VALUES (102, 'Cliff Wootton');
+INSERT INTO BOOK_AUTHOR VALUES (64, 102);
+INSERT INTO AUTHOR VALUES (103, 'et al');
+INSERT INTO BOOK_AUTHOR VALUES (64, 103);
+INSERT INTO AUTHOR VALUES (104, 'Nigel McFarlane');
+INSERT INTO BOOK_AUTHOR VALUES (64, 104);
+INSERT INTO BOOK VALUES (65, '2008-05-01', '', 'A Thousand Splendid Suns');
+INSERT INTO AUTHOR VALUES (105, 'Khaled Hosseini');
+INSERT INTO BOOK_AUTHOR VALUES (65, 105);
+INSERT INTO BOOK VALUES (66, '2004-04-12', '', 'The Tibetan Art of Positive Thinking: Skilful Thoughts for Successful Living');
+INSERT INTO AUTHOR VALUES (106, 'Christopher Hansard');
+INSERT INTO BOOK_AUTHOR VALUES (66, 106);
+INSERT INTO BOOK VALUES (67, '2008-07-29', '', 'Fucking Berlin: Studentin und Teilzeit-Hure');
+INSERT INTO AUTHOR VALUES (107, 'Sonia Rossi');
+INSERT INTO BOOK_AUTHOR VALUES (67, 107);
+INSERT INTO BOOK VALUES (68, '1999-10-21', '', 'Liar''s Poker: Playing the Money Markets');
+INSERT INTO AUTHOR VALUES (108, 'Michael Lewis');
+INSERT INTO BOOK_AUTHOR VALUES (68, 108);
+INSERT INTO BOOK VALUES (69, '1998-09-24', '', 'Clear Your Clutter with Feng Shui: Space Clearing Can Change Your Life');
+INSERT INTO AUTHOR VALUES (109, 'Karen Kingston');
+INSERT INTO BOOK_AUTHOR VALUES (69, 109);
+INSERT INTO BOOK VALUES (70, '1995-02-13', 'SEI Series in Software Engineering S', 'A Discipline for Software Engineering');
+INSERT INTO AUTHOR VALUES (110, 'Watts S. Humphrey');
+INSERT INTO BOOK_AUTHOR VALUES (70, 110);
+INSERT INTO BOOK VALUES (71, '2004-01-31', '', 'Das grosse Buch der vegetarischen K\374che.');
+INSERT INTO AUTHOR VALUES (111, 'Mahmud Darwish');
+INSERT INTO BOOK_AUTHOR VALUES (71, 111);
Modified: search/trunk/doc/reference/en/modules/getting-started.xml
===================================================================
--- search/trunk/doc/reference/en/modules/getting-started.xml 2008-10-14 14:25:27 UTC (rev 15346)
+++ search/trunk/doc/reference/en/modules/getting-started.xml 2008-10-14 18:53:41 UTC (rev 15347)
@@ -199,8 +199,8 @@
a working configuration you can start experimenting with other directory
providers (see <xref linkend="search-configuration-directory" />). Next to
the directory provider you also have to specify the default root directory
- for all indexes via <literal>hibernate.search.default.indexBase</literal>.
- </para>
+ for all indexes via
+ <literal>hibernate.search.default.indexBase</literal>.</para>
<para>Lets further assume that your application contains the Hibernate
managed classes <classname>example.Book</classname> and
@@ -548,20 +548,29 @@
<section>
<title>What's next</title>
- <para>The above paragraphs hopefully helped you getting started with
- Hibernate Search. You should by now have a file system based index and be
- able to search and retrieve a list of managed objects via Hibernate
- Search. The next step is to get more familiar with the overall
- architecture (<xref linkend="search-architecture" />) and explore the
- basic features in more detail.</para>
+ <para>The above paragraphs hopefully helped you getting an overview of
+ Hibernate Search. Using the maven archetype plugin and the following
+ command you can create an initial runnable maven project structure
+ populated with the example code of this tutorial.</para>
- <para>Two topics which where only briefly touched in this tutorial were
+ <para><programlisting>mvn archetype:create \
+ -DarchetypeGroupId=org.hibernate \
+ -DarchetypeArtifactId=hibernate-search-quickstart \
+ -DarchetypeVersion=3.1.0.Beta2 \
+ -DgroupId=my.company -DartifactId=quickstart</programlisting>Using the
+ maven project you can execute the examples, inspect the file system based
+ index and search and retrieve a list of managed objects. Just run
+ <emphasis>mvn package</emphasis> to compile the sources and run the unit
+ tests.</para>
+
+ <para>The next step after this tutorial is to get more familiar with the
+ overall architecture of Hibernate Search (<xref
+ linkend="search-architecture" />) and explore the basic features in more
+ detail. Two topics which where only briefly touched in this tutorial were
analyzer configuration (<xref linkend="analyzer" />) and field bridges
(<xref linkend="search-mapping-bridge" />), both important features
- required for more fine-grained indexing.</para>
-
- <para>More advanced topics cover clustering (<xref
- linkend="jms-backend" />) and large indexes handling (<xref
- linkend="search-configuration-directory-sharding" />).</para>
+ required for more fine-grained indexing. More advanced topics cover
+ clustering (<xref linkend="jms-backend" />) and large indexes handling
+ (<xref linkend="search-configuration-directory-sharding" />).</para>
</section>
</chapter>
15 years, 7 months
Hibernate SVN: r15346 - search/trunk/doc/reference/en/modules.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2008-10-14 10:25:27 -0400 (Tue, 14 Oct 2008)
New Revision: 15346
Modified:
search/trunk/doc/reference/en/modules/configuration.xml
search/trunk/doc/reference/en/modules/getting-started.xml
search/trunk/doc/reference/en/modules/mapping.xml
Log:
HSEARCH-231 - updated the reference guide
Modified: search/trunk/doc/reference/en/modules/configuration.xml
===================================================================
--- search/trunk/doc/reference/en/modules/configuration.xml 2008-10-13 19:25:17 UTC (rev 15345)
+++ search/trunk/doc/reference/en/modules/configuration.xml 2008-10-14 14:25:27 UTC (rev 15346)
@@ -22,8 +22,8 @@
~ 51 Franklin Street, Fifth Floor
~ Boston, MA 02110-1301 USA
-->
-
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="search-configuration">
<!-- $Id$ -->
@@ -562,8 +562,8 @@
</listitem>
<listitem>
- <para><filename>apache-solr-analyzer.jar</filename>: Additional
- analyzer infrastructure</para>
+ <para><filename>solr-*.jar</filename>: Additional analyzer
+ infrastructure</para>
</listitem>
</itemizedlist>
</section>
@@ -771,7 +771,7 @@
<entry>128</entry>
</row>
-
+
<row>
<entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].use_compound_file</literal></entry>
@@ -779,10 +779,11 @@
performing option. You may need to enable it to have the index
written to a single compound file to use less file handlers, but
increasing the number of permitted file handlers is usually a
- preferred solution.</para>
- <para>Especially when synchronizing indexes using JMS avoid
- this option as it will copy the complete index each time.</para>
- <para>Boolean parameter, use "<literal>true</literal>" or "<literal>false</literal>".</para></entry>
+ preferred solution.</para> <para>Especially when synchronizing
+ indexes using JMS avoid this option as it will copy the complete
+ index each time.</para> <para>Boolean parameter, use
+ "<literal>true</literal>" or
+ "<literal>false</literal>".</para></entry>
<entry>false</entry>
</row>
@@ -790,4 +791,4 @@
</tgroup>
</table>
</section>
-</chapter>
\ No newline at end of file
+</chapter>
Modified: search/trunk/doc/reference/en/modules/getting-started.xml
===================================================================
--- search/trunk/doc/reference/en/modules/getting-started.xml 2008-10-13 19:25:17 UTC (rev 15345)
+++ search/trunk/doc/reference/en/modules/getting-started.xml 2008-10-14 14:25:27 UTC (rev 15346)
@@ -22,8 +22,8 @@
~ 51 Franklin Street, Fifth Floor
~ Boston, MA 02110-1301 USA
-->
-
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="getting-started">
<!-- $Id$ -->
@@ -98,7 +98,7 @@
<section>
<title>Maven</title>
- <para>Instead of managing all dependencies yourself maven users have the
+ <para>Instead of managing all dependencies manually, maven users have the
possibility to use the <ulink
url="http://repository.jboss.com/maven2">JBoss maven repository</ulink>.
Just add the JBoss repository url to the <emphasis>repositories</emphasis>
@@ -120,7 +120,7 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search</artifactId>
- <version>3.1.0.Beta1</version>
+ <version>3.1.0.Beta2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
@@ -132,15 +132,37 @@
<artifactId>hibernate-entitymanager</artifactId>
<version>3.4.0.CR1</version>
</dependency>
+<dependency>
+ <groupId>org.apache.solr</groupId>
+ <artifactId>solr-common</artifactId>
+ <version>1.3.0</version>
+</dependency>
+<dependency>
+ <groupId>org.apache.solr</groupId>
+ <artifactId>solr-core</artifactId>
+ <version>1.3.0</version>
+</dependency>
+<dependency>
+ <groupId>org.apache.solr</groupId>
+ <artifactId>solr-lucene-snowball</artifactId>
+ <version>1.3.0</version>
+</dependency>
</programlisting>
- <para>Not all three dependencies are required.
- <emphasis>hibernate-search</emphasis> alone contains everything needed to
- use Hibernate Search. <emphasis>hibernate-annotations</emphasis> is only
- needed if you use non Hibernate Search annotations like we do in the
- examples of this tutorial. Last but not least,
- <emphasis>hibernate-entitymanager</emphasis> is only required if you use
- Hibernate Search in conjunction with JPA.</para>
+ <para>Not all dependencies are required. Only the
+ <emphasis>hibernate-search</emphasis> dependeny is mandatory. This
+ dependeny, together with its required transitive dependencies, contains
+ everything needed to use Hibernate Search.
+ <emphasis>hibernate-annotations</emphasis> is only needed if you want to
+ use annotations to configure your domain model as we do in this tutorial.
+ However, even if you choose not to use Hibernate Annotations you will
+ still have to use the Hibernate Search specific annotations to configure
+ your Lucene index. Currently there is no XML configuration option
+ available for Hibernate Search.
+ <emphasis>hibernate-entitymanager</emphasis> is required if you want to
+ use Hibernate Search in conjunction with JPA. Finally, the Solr
+ dependencies are only needed if you want to utilize Solr's analyzer
+ framework. More about this later.</para>
</section>
<section>
@@ -153,10 +175,21 @@
<literal>hibernate.cfg.xml</literal>. If you are using Hibernate via JPA
you can also add the properties to <literal>persistence.xml</literal>. The
good news is that for standard use most properties offer a sensible
- default.</para>
+ default. Within <filename>persistence.xml</filename> this could look like
+ this:</para>
- <para>Apache Lucene has a notion of <literal>Directory</literal> to store
- the index files. Hibernate Search handles the initialization and
+ <para><programlisting>
+...
+<property name="hibernate.search.default.directory_provider"
+ value="org.hibernate.search.store.FSDirectoryProvider"/>
+
+<property name="hibernate.search.default.indexBase" value="/var/lucene/indexes"/>
+...
+ </programlisting>First you have to tell Hibernate Search which
+ <classname>DirectoryProvider</classname> to use. This can be achieved by
+ setting the <literal>hibernate.search.default.directory_provider</literal>
+ property. Apache Lucene has a notion of <literal>Directory</literal> to
+ store the index files. Hibernate Search handles the initialization and
configuration of a Lucene <literal>Directory</literal> instance via a
<literal>DirectoryProvider</literal>. In this tutorial we will use a
subclass of <literal>DirectoryProvider</literal> called
@@ -164,12 +197,16 @@
to physically inspect the Lucene indexes created by Hibernate Search (eg
via <ulink url="http://www.getopt.org/luke/">Luke</ulink>). Once you have
a working configuration you can start experimenting with other directory
- providers (see <xref linkend="search-configuration-directory" />).</para>
+ providers (see <xref linkend="search-configuration-directory" />). Next to
+ the directory provider you also have to specify the default root directory
+ for all indexes via <literal>hibernate.search.default.indexBase</literal>.
+ </para>
- <para>Lets assume that your application contains the Hibernate managed
- class <classname>example.Book</classname> and you now want to add free
- text search capabilities to your application in order to search body and
- summary of the books contained in your database.</para>
+ <para>Lets further assume that your application contains the Hibernate
+ managed classes <classname>example.Book</classname> and
+ <classname>example.Author</classname> and you want to add free text search
+ capabilities to your application in order to search the books contained in
+ your database.</para>
<programlisting>
package example;
@@ -181,16 +218,13 @@
@GeneratedValue
private Integer id;
- private String body;
+ private String title;
- private String summary;
+ private String subtitle;
@ManyToMany
private Set<Author> authors = new HashSet<Author>();
- @ManyToOne
- private Author mainAuthor;
-
private Date publicationDate;
public Book() {
@@ -201,46 +235,83 @@
}
</programlisting>
- <para>First you have to tell Hibernate Search which
- <classname>DirectoryProvider</classname> to use. This can be achieved by
- setting the <literal>hibernate.search.default.directory_provider</literal>
- property. You also have to specify the default root directory for all
- indexes via <literal>hibernate.search.default.indexBase</literal>.</para>
-
- <programlisting>
+ <para><programlisting>
+package example;
...
-# the default directory provider
-hibernate.search.default.directory_provider = org.hibernate.search.store.FSDirectoryProvider
+@Entity
+public class Author {
-# the default base directory for the indecies
-hibernate.search.default.indexBase = /var/lucene/indexes
-...
- </programlisting>
+ @Id
+ @GeneratedValue
+ private Integer id;
- <para>Next you have to add three annotations to the
- <classname>Book</classname> class. The first annotation
- <literal>@Indexed</literal> marks <classname>Book</classname> as
- indexable. By design Hibernate Search needs to store an untokenized id in
- the index to ensure index unicity for a given entity.
- <literal>@DocumentId</literal> marks the property to use for this purpose.
- Most if not all the time, the property is the database primary key. Last
- but not least you have to index the fields you want to make searchable. In
- our example these fields are <literal>body</literal> and
- <literal>summary</literal>. Both properties get annotated with
- <literal>@Field</literal>. The property
+ private String name;
+
+ public Author() {
+ }
+
+ // standard getters/setters follow here
+ ...
+}
+
+</programlisting></para>
+
+ <para>To achieve this you have to add a few annotations to the
+ <classname>Book</classname> and <classname>Author</classname> class. The
+ first annotation <literal>@Indexed</literal> marks
+ <classname>Book</classname> as indexable. By design Hibernate Search needs
+ to store an untokenized id in the index to ensure index unicity for a
+ given entity. <literal>@DocumentId</literal> marks the property to use for
+ this purpose and is in most cases the same as the database primary
+ key.</para>
+
+ <para>Next you have to mark the fields you want to make searchable. Let's
+ start with <literal>title</literal> and <literal>subtitle</literal> and
+ annotate both with <literal>@Field</literal>. The parameter
<literal>index=Index.TOKENIZED</literal> will ensure that the text will be
- tokenized using the default Lucene analyzer whereas
- <literal>store=Store.NO</literal> ensures that the actual data will not be
- stored in the index. Usually, tokenizing means chunking a sentence into
- individual words (and potentially excluding common words like
- <literal>a</literal>, <literal>the </literal>etc).</para>
+ tokenized using the default Lucene analyzer. Usually, tokenizing means
+ chunking a sentence into individual words and potentially excluding common
+ words like <literal>'a'</literal> or '<literal>the</literal>'. We will
+ talk more about analyzers a little later on. The second parameter we
+ specify within <literal>@Field</literal>,<literal>
+ store=Store.NO</literal>, ensures that the actual data will not be stored
+ in the index. This is the default settings and probably a good choice
+ unless you want to avoid database roundtrips and retrieve the indexed data
+ via projections (<xref linkend="projections" />). Without projections,
+ Hibernate Search will per default execute the Lucene query in order to
+ find the database identifiers of the entities matching the query critera
+ and use these identifiers to retrieve managed objects from the database.
+ Is it not better then to always use projections? The answer is no, since
+ projections only returns object arrays and not managed entities. The
+ decision for or against projection has to be made on a case to case
+ basis.</para>
- <para>These settings are sufficient for an initial test. For more details
- on entity mapping refer to <xref linkend="search-mapping-entity" />. In
- case you want to store and retrieve the indexed data in order to avoid
- database roundtrips, refer to projections in <xref
- linkend="projections" /></para>
+ <para>After this short look under the hood let's go back to annotating the
+ <classname>Book</classname> class. Another annotation we have not yet
+ discussed is <literal>@DateBridge</literal>. This annotation is one of the
+ built-in field bridges in Hibernate Search. The Lucene index is purely
+ string based. For this reason Hibernate Search must convert the data types
+ of the indexed fields to strings and vice versa. A range of predefined
+ bridges are provided, including the <classname>DateBridge</classname>
+ which will convert a <classname>java.util.Date</classname> into a
+ <classname>String</classname> with the specified resolution. For more
+ details see <xref linkend="search-mapping-bridge" />.</para>
+ <para>This leaves us with <literal>@IndexedEmbedded. </literal>This
+ annotation is used to indexed associated entities
+ (<literal>@ManyToMany</literal>, <literal>@*ToOne</literal> and
+ <literal>@Embedded</literal>) as part of the owning entity. This is needed
+ since a Lucene index document is a flat data structure which does not know
+ anything about object relations. To ensure that the author's name wil be
+ searchable you have to make sure that the names are indexed as part of the
+ book itself. On top of <literal>@IndexedEmbedded</literal> you will also
+ have to mark all fields of the associated entity you want to have included
+ in the index with <literal>@Indexed</literal>. For more dedails see <xref
+ linkend="search-mapping-associated" />.</para>
+
+ <para>These settings should be sufficient for now. For more details on
+ entity mapping refer to <xref linkend="search-mapping-entity" />.</para>
+
<programlisting>
package example;
...
@@ -254,17 +325,17 @@
private Integer id;
<emphasis role="bold">@Field(index=Index.TOKENIZED, store=Store.NO)</emphasis>
- private String body;
+ private String title;
<emphasis role="bold">@Field(index=Index.TOKENIZED, store=Store.NO)</emphasis>
- private String summary;
+ private String subtitle;
+ <emphasis role="bold">@IndexedEmbedded</emphasis>
@ManyToMany
private Set<Author> authors = new HashSet<Author>();
- @ManyToOne
- private Author mainAuthor;
-
+<emphasis role="bold"> @Field(index = Index.UN_TOKENIZED, store = Store.YES)
+ @DateBridge(resolution = Resolution.DAY)</emphasis>
private Date publicationDate;
public Book() {
@@ -274,12 +345,33 @@
...
}
</programlisting>
+
+ <programlisting>
+package example;
+...
+@Entity
+public class Author {
+
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ <emphasis role="bold">@Field(index=Index.TOKENIZED, store=Store.NO)</emphasis>
+ private String name;
+
+ public Author() {
+ }
+
+ // standard getters/setters follow here
+ ...
+}
+ </programlisting>
</section>
<section>
<title>Indexing</title>
- <para>Hibernate Search will index transparently every entity persisted,
+ <para>Hibernate Search will transparently index every entity persisted,
updated or removed through Hibernate Core. However, you have to trigger an
inital indexing to populate the Lucene index with the data already present
in your database. Once you have added the above properties and annotations
@@ -320,9 +412,8 @@
<title>Searching</title>
<para>Now it is time to execute a first search. The following code will
- prepare a query against the fields <literal>summary</literal> and
- <literal>body</literal>, execute it and return a list of
- <classname>Book</classname>s:</para>
+ prepare a query against the indexed fields, execute it and return a list
+ of <classname>Book</classname>s:</para>
<para>Example using Hibernate Session:</para>
@@ -331,7 +422,7 @@
Transaction tx = fullTextSession.beginTransaction();
-MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{"summary", "body"},
+MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{"title", "subtitle", "authors.name", "publicationDate"},
new StandardAnalyzer());
Query query = parser.parse( "Java rocks!" );
org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery( query, Book.class );
@@ -348,7 +439,7 @@
FullTextEntityManager fullTextEntityManager =
org.hibernate.hibernate.search.jpa.Search.getFullTextEntityManager(em);
-MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{"summary", "body"},
+MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{"title", "subtitle", "authors.name", "publicationDate"},
new StandardAnalyzer());
Query query = parser.parse( "Java rocks!" );
org.hibernate.Query hibQuery = fullTextEntityManager.createFullTextQuery( query, Book.class );
@@ -359,12 +450,14 @@
<section>
<title>Analyzer</title>
- <para>Assume that one of your indexed book entities contains the text
- "Java rocks" and you want to get hits for all of the following queries:
- "rock", "rocks", "rocked" and "rocking". In Lucene this can be achieved by
- choosing an analyzer class which applies word stemming during the indexing
- process. Hibernate Search offers several ways to configure the analyzer to
- use (see <xref linkend="analyzer" />):</para>
+ <para>Assume that one of your indexed book entities has the title
+ "Refactoring: Improving the Design of Existing Code" and you want to get
+ hits for all of the following queries: "refactor", "refactors",
+ "refactored" and "refactoring". In Lucene this can be achieved by choosing
+ an analyzer class which applies word stemming during the indexing
+ <emphasis role="bold">and</emphasis> search process. Hibernate Search
+ offers several ways to configure the analyzer to use (see <xref
+ linkend="analyzer" />):</para>
<itemizedlist>
<listitem>
@@ -374,70 +467,81 @@
</listitem>
<listitem>
- <para>Setting the <literal>Analyzer</literal> annotation at the entity
- level.</para>
+ <para>Setting the <literal><literal>@Analyzer</literal></literal>
+ annotation at the entity level.</para>
</listitem>
<listitem>
- <para>Setting the <literal>Analyzer</literal> annotation at the field
- level.</para>
+ <para>Setting the <literal>@<literal>Analyzer</literal></literal>
+ annotation at the field level.</para>
</listitem>
</itemizedlist>
- <para>Hibernate Search also introduces the notion of analyzer definitions
- which allow you to manage and reuse analyzers. This infrastructure is
- supported by the Solr analyzer framework (see <xref
- linkend="analyzer" />). The following example uses the entity level
- annotation to apply a English language analyzer which would help you to
- achieve your goal. The class <classname>EnglishAnalyzer</classname> is a
- custom class using the Snowball English Stemmer from the <ulink
- url="http://lucene.apache.org/java/docs/lucene-sandbox/">Lucene
- Sandbox</ulink>.</para>
+ <para>When using the <literal>@Analyzer</literal> annotation one can
+ either specify the fully qualified classname of the analyzer to use or one
+ can refer to an analyzer definition defined by the
+ <literal>@AnalyzerDef</literal> annotation. In the latter case the Solr
+ analyzer framework with its factories approach can be used. To find out
+ more about the factory classes available you can either browse the Solr
+ JavaDoc or read the corresponding section on the <ulink
+ url="http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters">Solr
+ Wiki.</ulink> In the example a
+ <classname>StandardTokenizerFactory</classname> is used followed by two
+ filter factories, <classname>LowerCaseFilterFactory</classname> and
+ <classname>SnowballPorterFilterFactory</classname>. The standard tokenizer
+ splits words at punctuation characters and hyphens while keeping email
+ addresses and internet hostnames intact. It is a good general purpose
+ tokenizer. The lowercase filter lowercases then the letters in each token
+ whereas the snowball filter finally applies the actual language
+ stemming.</para>
+ <para>Generally, when using the Solr framework you have to start with a
+ tokenizer followed by an arbitrary number of filters.</para>
+
<programlisting>
-package example.Book
+
+package example;
...
@Entity
@Indexed
-<emphasis role="bold">@Analyzer(impl = example.EnglishAnalyzer.class)</emphasis>
+<emphasis role="bold">@AnalyzerDef(name = "customanalyzer",
+ tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
+ filters = {
+ @TokenFilterDef(factory = LowerCaseFilterFactory.class),
+ @TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = {
+ @Parameter(name = "language", value = "English")
+ })
+ })</emphasis>
public class Book {
@Id
+ @GeneratedValue
@DocumentId
private Integer id;
@Field(index=Index.TOKENIZED, store=Store.NO)
- private String body;
+ <emphasis role="bold">@Analyzer(definition = "customanalyzer")</emphasis>
+ private String title;
@Field(index=Index.TOKENIZED, store=Store.NO)
- private String summary;
+ <emphasis role="bold">@Analyzer(definition = "customanalyzer")</emphasis>
+ private String subtitle;
+ @IndexedEmbedded
@ManyToMany
private Set<Author> authors = new HashSet<Author>();
- @ManyToOne private Author mainAuthor;
+<emphasis role="bold"> </emphasis> @Field(index = Index.UN_TOKENIZED, store = Store.YES)
+ @DateBridge(resolution = Resolution.DAY)
private Date publicationDate;
public Book() {
}
// standard getters/setters follow here
-...
+ ...
}
-public class EnglishAnalyzer extends Analyzer {
- /**
- * {@inheritDoc}
- */
- @Override
- public TokenStream tokenStream(String fieldName, Reader reader) {
- TokenStream result = new StandardTokenizer(reader);
- result = new StandardFilter(result);
- result = new LowerCaseFilter(result);
- result = new SnowballFilter(result, name);
- return result;
- }
-}
</programlisting>
</section>
@@ -460,4 +564,4 @@
linkend="jms-backend" />) and large indexes handling (<xref
linkend="search-configuration-directory-sharding" />).</para>
</section>
-</chapter>
\ No newline at end of file
+</chapter>
Modified: search/trunk/doc/reference/en/modules/mapping.xml
===================================================================
--- search/trunk/doc/reference/en/modules/mapping.xml 2008-10-13 19:25:17 UTC (rev 15345)
+++ search/trunk/doc/reference/en/modules/mapping.xml 2008-10-14 14:25:27 UTC (rev 15346)
@@ -22,8 +22,8 @@
~ 51 Franklin Street, Fifth Floor
~ Boston, MA 02110-1301 USA
-->
-
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="search-mapping" revision="3">
<!-- $Id$ -->
@@ -260,8 +260,8 @@
bridges.</para>
</section>
- <section>
- <title>Embedded and associated objects</title>
+ <section id="search-mapping-associated">
+ <title>Embedded and associated objects </title>
<para>Associated objects as well as embedded objects can be indexed as
part of the root entity index. It is necessary if you expect to search a
@@ -603,7 +603,7 @@
reuse of each individual component and let you build your ideal
analyzer ns a very flexible way (just like a lego). This
infrastructure is supported by the Solr analyzer framework. Make sure
- to add <filename>apache-solr-*.jar</filename> to your classpath to use
+ to add <filename>solr-*.jar</filename> to your classpath to use
analyzer definitions: this jar is distributed with your distribution
of Hibernate Search and is a striped down version of the Solr
jar.</para>
@@ -766,7 +766,7 @@
<entry>Reduces a word to it's root in a given language. (eg.
protect, protects, protection share the same root). Using such
- a filter allows searches matching related words. </entry>
+ a filter allows searches matching related words.</entry>
<entry><para><literal>language</literal>: Danish, Dutch,
English, Finnish, French, German, Italian, Norwegian,
@@ -1163,19 +1163,27 @@
</section>
<section id="provided-id">
- <title>Providing your own id</title>
-
- <para>You can provide your own id for Hibernate Search if you are extending the internals. You will have to generate a unique value so it can be given to Lucene to
- be indexed. This will have to be given to Hibernate Search when you create an org.hibernate.search.Work object - the document id is required in the constructor.
- </para>
-
- <section id="@ProvidedId">
- <title>The @ProvidedId annotation</title>
-
- <para>Unlike conventional Hibernate Search API and @DocumentId, this annotation is used on the class and not a field. You also can provide your own bridge implementation when you put in this annotation by calling the bridge() which is on @ProvidedId. Also, if you annotate a class with @ProvidedId, your subclasses will also get the annotation - but it is not done by using the java.lang.annotations.@Inherited. Be sure however, to <emphasis>not</emphasis> use this annotation with @DocumentId as your system will break.
- </para>
-
- <programlisting>
+ <title>Providing your own id</title>
+
+ <para>You can provide your own id for Hibernate Search if you are
+ extending the internals. You will have to generate a unique value so it
+ can be given to Lucene to be indexed. This will have to be given to
+ Hibernate Search when you create an org.hibernate.search.Work object - the
+ document id is required in the constructor.</para>
+
+ <section id="@ProvidedId">
+ <title>The @ProvidedId annotation</title>
+
+ <para>Unlike conventional Hibernate Search API and @DocumentId, this
+ annotation is used on the class and not a field. You also can provide
+ your own bridge implementation when you put in this annotation by
+ calling the bridge() which is on @ProvidedId. Also, if you annotate a
+ class with @ProvidedId, your subclasses will also get the annotation -
+ but it is not done by using the java.lang.annotations.@Inherited. Be
+ sure however, to <emphasis>not</emphasis> use this annotation with
+ @DocumentId as your system will break.</para>
+
+ <programlisting>
@ProvidedId (bridge = org.my.own.package.MyCustomBridge)
@Indexed
@@ -1189,7 +1197,7 @@
}
- </programlisting>
- </section>
- </section>
-</chapter>
\ No newline at end of file
+ </programlisting>
+ </section>
+ </section>
+</chapter>
15 years, 7 months
Hibernate SVN: r15345 - search/trunk/doc/reference.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2008-10-13 15:25:17 -0400 (Mon, 13 Oct 2008)
New Revision: 15345
Modified:
search/trunk/doc/reference/docbook-common-build.xml
Log:
HSEARCH-231 - improved dependency resolution in build
Modified: search/trunk/doc/reference/docbook-common-build.xml
===================================================================
--- search/trunk/doc/reference/docbook-common-build.xml 2008-10-13 19:06:38 UTC (rev 15344)
+++ search/trunk/doc/reference/docbook-common-build.xml 2008-10-13 19:25:17 UTC (rev 15345)
@@ -61,16 +61,10 @@
<xinclude in="${basedir}/${lang}/master.xml" out="${build.dir}/${lang}/master.xml"/>
</target>
- <target name="lang.all">
+ <target name="lang.all" depends="xinclude,lang.docpdf,lang.dochtml,lang.dochtmlsingle,lang.htmlmisc">
<!-- Compile the documentation for a single language in all formats. -->
- <antcall target="xinclude"/>
- <antcall target="lang.docpdf"/>
- <antcall target="lang.dochtml"/>
- <antcall target="lang.dochtmlsingle"/>
- <antcall target="lang.htmlmisc"/>
</target>
-
<target name="lang.docpdf.prepare">
<!-- Copy all the images to the output location, will be removed later. -->
15 years, 7 months
Hibernate SVN: r15344 - in search/trunk/doc/reference: en and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2008-10-13 15:06:38 -0400 (Mon, 13 Oct 2008)
New Revision: 15344
Added:
search/trunk/doc/reference/support/lib/xinclude-task-0.2.jar
search/trunk/doc/reference/support/lib/xincluder.jar
Removed:
search/trunk/doc/reference/.cvsignore
Modified:
search/trunk/doc/reference/build.xml
search/trunk/doc/reference/docbook-common-build.xml
search/trunk/doc/reference/en/master.xml
search/trunk/doc/reference/en/modules/architecture.xml
search/trunk/doc/reference/en/modules/batchindex.xml
search/trunk/doc/reference/en/modules/configuration.xml
search/trunk/doc/reference/en/modules/getting-started.xml
search/trunk/doc/reference/en/modules/lucene-native.xml
search/trunk/doc/reference/en/modules/mapping.xml
search/trunk/doc/reference/en/modules/optimize.xml
search/trunk/doc/reference/en/modules/query.xml
Log:
HSEARCH-231 - switched to use xi:includes for the modules in order to use the latest version xml mind editor. This change will also help to switch later to the maven jdocbook plugin. In order to use xi:include I had to add one more intermediate target using xinclude.
Deleted: search/trunk/doc/reference/.cvsignore
===================================================================
(Binary files differ)
Modified: search/trunk/doc/reference/build.xml
===================================================================
--- search/trunk/doc/reference/build.xml 2008-10-13 15:29:23 UTC (rev 15343)
+++ search/trunk/doc/reference/build.xml 2008-10-13 19:06:38 UTC (rev 15344)
@@ -3,6 +3,16 @@
<import file="docbook-common-build.xml"/>
<target name="all.doc" depends="clean">
+ <echo>
+ To build the reference docs for a particular language only, use "ant -Dlang=en", for
+ example, and call either lang.all, lang.docpdf, lang.dochtml, or lang.dochtmlsingle
+ for the target of your choice.
+
+ You can also call lang.section-check to track down missing identifiers in a particular
+ language, or you can call lang.revdiff to get a difference report for a particular
+ language, compared with the English reference.
+ </echo>
+
<!-- TRANSLATOR: Duplicate this call for your language -->
<antcall target="lang.all">
<param name="docname" value="hibernate_search"/>
Modified: search/trunk/doc/reference/docbook-common-build.xml
===================================================================
--- search/trunk/doc/reference/docbook-common-build.xml 2008-10-13 15:29:23 UTC (rev 15343)
+++ search/trunk/doc/reference/docbook-common-build.xml 2008-10-13 19:06:38 UTC (rev 15344)
@@ -1,29 +1,20 @@
-<!--
- To build the reference docs for a particular language only, use "ant -Dlang=en", for
- example, and call either lang.all, lang.docpdf, lang.dochtml, or lang.dochtmlsingle
- for the target of your choice.
-
- You can also call lang.section-check to track down missing identifiers in a particular
- language, or you can call lang.revdiff to get a difference report for a particular
- language, compared with the English reference.
--->
<project name="ReferenceDocumentation" default="all.doc" basedir=".">
<!-- Allow this to be overriden by others importing this project. -->
<dirname property="imported.basedir" file="${ant.file.ReferenceDocumentation}"/>
<!-- Set build directories for all formats. -->
- <property name="build.dir" value="${basedir}/build"/>
+ <property name="build.dir" value="${basedir}/build"/>
<!-- Support files for build process. -->
- <property name="support.dir" value="${imported.basedir}/support"/>
+ <property name="support.dir" value="${imported.basedir}/support"/>
<!-- Base name for documentation artifacts. -->
- <property name="docname" value="hibernate_reference"/>
+ <property name="docname" value="hibernate_reference"/>
<!-- Set DocBook stylesheets. -->
- <property name="db.style.fopdf" value="fopdf.xsl"/>
- <property name="db.style.html" value="html_chunk.xsl"/>
- <property name="db.style.htmlsingle" value="html.xsl"/>
+ <property name="db.style.fopdf" value="fopdf.xsl"/>
+ <property name="db.style.html" value="html_chunk.xsl"/>
+ <property name="db.style.htmlsingle" value="html.xsl"/>
<!-- Classpath for the build tools. -->
<path id="lib.classpath">
@@ -32,6 +23,8 @@
</fileset>
</path>
+ <taskdef name="xinclude" classname="org.znerd.xincludetask.XIncludeTask" classpathref="lib.classpath"/>
+
<!-- ################################################################## -->
<target name="all.doc"
@@ -39,38 +32,38 @@
description="Compile documentation for all languages and all formats.">
<!-- TRANSLATOR: Duplicate this line for your language -->
- <antcall target="lang.all"><param name="lang" value="en"/></antcall>
- <antcall target="lang.all"><param name="lang" value="fr"/></antcall>
- <!-- TODO: These translations need updating before we can enable them...
- <antcall target="lang.all"><param name="lang" value="ja"/></antcall>
- <antcall target="lang.all"><param name="lang" value="ko"/></antcall>
- <antcall target="lang.all"><param name="lang" value="zh-cn"/></antcall>
- -->
-
+ <antcall target="lang.all">
+ <param name="lang" value="en"/>
+ </antcall>
+ <!--antcall target="lang.all">
+ <param name="lang" value="fr"/>
+ </antcall-->
</target>
<target name="all.revdiff"
description="Generates a diff report for all translated versions.">
<!-- TRANSLATOR: Duplicate this line for your language -->
- <antcall target="lang.revdiff"><param name="lang" value="fr"/></antcall>
- <antcall target="lang.revdiff"><param name="lang" value="ko"/></antcall>
- <antcall target="lang.revdiff"><param name="lang" value="ja"/></antcall>
- <antcall target="lang.revdiff"><param name="lang" value="zh-cn"/></antcall>
-
+ <antcall target="lang.revdiff">
+ <param name="lang" value="fr"/>
+ </antcall>
</target>
<!-- ################################################################## -->
<target name="clean">
-
<!-- Delete build directory. -->
<delete dir="${build.dir}"/>
+ </target>
+ <target name="xinclude" description="Resolve xi:include references and generate a complete master document.">
+ <mkdir dir="${build.dir}/${lang}"/>
+ <xinclude in="${basedir}/${lang}/master.xml" out="${build.dir}/${lang}/master.xml"/>
</target>
- <target name="lang.all">
+ <target name="lang.all">
<!-- Compile the documentation for a single language in all formats. -->
+ <antcall target="xinclude"/>
<antcall target="lang.docpdf"/>
<antcall target="lang.dochtml"/>
<antcall target="lang.dochtmlsingle"/>
@@ -90,11 +83,12 @@
</copy>
<!-- Create the XSL/FO temporary file. -->
- <java classname="com.icl.saxon.StyleSheet" fork="true" dir="${basedir}" maxmemory="128m" >
+ <java classname="com.icl.saxon.StyleSheet" fork="true" dir="${basedir}" maxmemory="128m">
<classpath refid="lib.classpath"/>
<arg value="-o"/>
<arg value="${build.dir}/${lang}/pdf/docbook_fop.tmp"/>
- <arg value="${basedir}/${lang}/master.xml"/>
+
+ <arg value="${build.dir}/${lang}/master.xml"/>
<arg value="${basedir}/${lang}/styles/${db.style.fopdf}"/>
</java>
@@ -110,7 +104,7 @@
</copy>
<!-- Create a PDF from the XSL/FO, using customized fop userconfig.xml -->
- <java classname="org.apache.fop.apps.Fop" fork="true" dir="${basedir}" maxmemory="128m" >
+ <java classname="org.apache.fop.apps.Fop" fork="true" dir="${basedir}" maxmemory="128m">
<classpath refid="lib.classpath"/>
<arg value="-c"/>
<arg value="${basedir}/${lang}/fop/userconfig.xml"/>
@@ -128,29 +122,29 @@
</java>
</target>
- <target name="lang.docpdf" depends="lang.docpdf.normal,lang.docpdf.customized"
+ <target name="lang.docpdf" depends="xinclude,lang.docpdf.normal,lang.docpdf.customized"
description="Generates the PDF documentation only for a language (set lang)">
<!-- House keeping,delete temporary files. -->
<delete>
<fileset dir="${build.dir}/${lang}/pdf" excludes="**/*.pdf"/>
</delete>
- <delete dir="${build.dir}/${lang}/pdf/images"/>
+ <delete dir="${build.dir}/${lang}/pdf/images"/>
</target>
- <target name="lang.dochtml"
+ <target name="lang.dochtml" depends="xinclude"
description="Generates the HTML documentation only for a language (set lang)">
<mkdir dir="${build.dir}/${lang}/html/"/>
<java classname="com.icl.saxon.StyleSheet" fork="true" dir="${build.dir}/${lang}/html">
<classpath refid="lib.classpath"/>
- <arg value="${basedir}/${lang}/master.xml"/>
+ <arg value="${build.dir}/${lang}/master.xml"/>
<arg value="${basedir}/${lang}/styles/${db.style.html}"/>
</java>
</target>
- <target name="lang.dochtmlsingle"
- description="Generates the single-page HTML documentation only for a language (set lang)">
+ <target name="lang.dochtmlsingle" depends="xinclude"
+ description="Generates the single-page HTML documentation only for a language (set lang)">
<mkdir dir="${build.dir}/${lang}/html_single/"/>
@@ -158,7 +152,7 @@
<classpath refid="lib.classpath"/>
<arg value="-o"/>
<arg value="${build.dir}/${lang}/html_single/index.html"/>
- <arg value="${basedir}/${lang}/master.xml"/>
+ <arg value="${build.dir}/${lang}/master.xml"/>
<arg value="${basedir}/${lang}/styles/${db.style.htmlsingle}"/>
</java>
</target>
@@ -180,28 +174,28 @@
</target>
- <target name="lang.revdiff"
+ <target name="lang.revdiff" depends="xinclude"
description="Reports difference between English and translation (set lang)">
- <mkdir dir="${build.dir}"/>
+ <mkdir dir="${build.dir}"/>
<taskdef name="revdiff"
- classname="org.hibernate.docproc.revdiff.RevDiffReportTask"
- classpathref="lib.classpath">
+ classname="org.hibernate.docproc.revdiff.RevDiffReportTask"
+ classpathref="lib.classpath">
</taskdef>
- <revdiff original="${basedir}/en/master.xml"
- copy="${basedir}/${lang}/master.xml"
+ <revdiff original="${build.dir}/en/master.xml"
+ copy="${build.dir}/${lang}/master.xml"
report="${build.dir}/status_${lang}.html"/>
</target>
- <target name="lang.section-check" depends="lang.dochtml"
+ <target name="lang.section-check" depends="xinclude,lang.dochtml"
description="Reports missing unique chapter/section identifiers (set lang)">
<java classname="com.icl.saxon.StyleSheet" fork="true" dir="${build.dir}/${lang}/html">
<classpath refid="lib.classpath"/>
- <arg value="${basedir}/${lang}/master.xml"/>
+ <arg value="${build.dir}/${lang}/master.xml"/>
<arg value="${support.dir}/section-check.xsl"/>
</java>
</target>
Modified: search/trunk/doc/reference/en/master.xml
===================================================================
--- search/trunk/doc/reference/en/master.xml 2008-10-13 15:29:23 UTC (rev 15343)
+++ search/trunk/doc/reference/en/master.xml 2008-10-13 19:06:38 UTC (rev 15344)
@@ -1,16 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id$ -->
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3CR3//EN"
-"../support/docbook-dtd/docbookx.dtd" [
-<!ENTITY getting-started SYSTEM "modules/getting-started.xml">
-<!ENTITY architecture SYSTEM "modules/architecture.xml">
-<!ENTITY configuration SYSTEM "modules/configuration.xml">
-<!ENTITY mapping SYSTEM "modules/mapping.xml">
-<!ENTITY query SYSTEM "modules/query.xml">
-<!ENTITY batchindex SYSTEM "modules/batchindex.xml">
-<!ENTITY optimize SYSTEM "modules/optimize.xml">
-<!ENTITY lucene-native SYSTEM "modules/lucene-native.xml">
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+ <!ENTITY versionNumber "3.1.0.Beta1">
+ <!ENTITY copyrightYear "2004">
+ <!ENTITY copyrightHolder "Red Hat Middleware, LLC.">
]>
+
<book lang="en">
<bookinfo>
<title>Hibernate Search</title>
@@ -19,7 +37,7 @@
<subtitle>Reference Guide</subtitle>
- <releaseinfo>3.1.0.Beta1</releaseinfo>
+ <releaseinfo>&versionNumber;</releaseinfo>
<mediaobject>
<imageobject>
@@ -50,19 +68,13 @@
</preface>
- &getting-started;
+ <xi:include href="modules/getting-started.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="modules/architecture.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="modules/configuration.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="modules/mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="modules/query.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="modules/batchindex.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="modules/optimize.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="modules/lucene-native.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
- &architecture;
-
- &configuration;
-
- &mapping;
-
- &query;
-
- &batchindex;
-
- &optimize;
-
- &lucene-native;
</book>
\ No newline at end of file
Modified: search/trunk/doc/reference/en/modules/architecture.xml
===================================================================
--- search/trunk/doc/reference/en/modules/architecture.xml 2008-10-13 15:29:23 UTC (rev 15343)
+++ search/trunk/doc/reference/en/modules/architecture.xml 2008-10-13 19:06:38 UTC (rev 15344)
@@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="search-architecture">
<!-- $Id$ -->
Modified: search/trunk/doc/reference/en/modules/batchindex.xml
===================================================================
--- search/trunk/doc/reference/en/modules/batchindex.xml 2008-10-13 15:29:23 UTC (rev 15343)
+++ search/trunk/doc/reference/en/modules/batchindex.xml 2008-10-13 19:06:38 UTC (rev 15344)
@@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="search-batchindex">
<!-- $Id$ -->
Modified: search/trunk/doc/reference/en/modules/configuration.xml
===================================================================
--- search/trunk/doc/reference/en/modules/configuration.xml 2008-10-13 15:29:23 UTC (rev 15343)
+++ search/trunk/doc/reference/en/modules/configuration.xml 2008-10-13 19:06:38 UTC (rev 15344)
@@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="search-configuration">
<!-- $Id$ -->
Modified: search/trunk/doc/reference/en/modules/getting-started.xml
===================================================================
--- search/trunk/doc/reference/en/modules/getting-started.xml 2008-10-13 15:29:23 UTC (rev 15343)
+++ search/trunk/doc/reference/en/modules/getting-started.xml 2008-10-13 19:06:38 UTC (rev 15344)
@@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="getting-started">
<!-- $Id$ -->
Modified: search/trunk/doc/reference/en/modules/lucene-native.xml
===================================================================
--- search/trunk/doc/reference/en/modules/lucene-native.xml 2008-10-13 15:29:23 UTC (rev 15343)
+++ search/trunk/doc/reference/en/modules/lucene-native.xml 2008-10-13 19:06:38 UTC (rev 15344)
@@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="search-lucene-native">
<!-- $Id$ -->
Modified: search/trunk/doc/reference/en/modules/mapping.xml
===================================================================
--- search/trunk/doc/reference/en/modules/mapping.xml 2008-10-13 15:29:23 UTC (rev 15343)
+++ search/trunk/doc/reference/en/modules/mapping.xml 2008-10-13 19:06:38 UTC (rev 15344)
@@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="search-mapping" revision="3">
<!-- $Id$ -->
Modified: search/trunk/doc/reference/en/modules/optimize.xml
===================================================================
--- search/trunk/doc/reference/en/modules/optimize.xml 2008-10-13 15:29:23 UTC (rev 15343)
+++ search/trunk/doc/reference/en/modules/optimize.xml 2008-10-13 19:06:38 UTC (rev 15344)
@@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="search-optimize">
<!-- $Id$ -->
Modified: search/trunk/doc/reference/en/modules/query.xml
===================================================================
--- search/trunk/doc/reference/en/modules/query.xml 2008-10-13 15:29:23 UTC (rev 15343)
+++ search/trunk/doc/reference/en/modules/query.xml 2008-10-13 19:06:38 UTC (rev 15344)
@@ -1,4 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="search-query" xreflabel="Querying">
<!-- $Id$ -->
Added: search/trunk/doc/reference/support/lib/xinclude-task-0.2.jar
===================================================================
(Binary files differ)
Property changes on: search/trunk/doc/reference/support/lib/xinclude-task-0.2.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: search/trunk/doc/reference/support/lib/xincluder.jar
===================================================================
(Binary files differ)
Property changes on: search/trunk/doc/reference/support/lib/xincluder.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
15 years, 7 months
Hibernate SVN: r15343 - in core/trunk/core/src: main/java/org/hibernate/dialect and 6 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-13 11:29:23 -0400 (Mon, 13 Oct 2008)
New Revision: 15343
Added:
core/trunk/core/src/main/java/org/hibernate/dialect/resolver/
core/trunk/core/src/main/java/org/hibernate/dialect/resolver/AbstractDialectResolver.java
core/trunk/core/src/main/java/org/hibernate/dialect/resolver/BasicDialectResolver.java
core/trunk/core/src/main/java/org/hibernate/dialect/resolver/BasicSQLExceptionConverter.java
core/trunk/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java
core/trunk/core/src/main/java/org/hibernate/dialect/resolver/DialectResolver.java
core/trunk/core/src/main/java/org/hibernate/dialect/resolver/DialectResolverSet.java
core/trunk/core/src/main/java/org/hibernate/dialect/resolver/StandardDialectResolver.java
core/trunk/core/src/test/java/org/hibernate/dialect/
core/trunk/core/src/test/java/org/hibernate/dialect/Mocks.java
core/trunk/core/src/test/java/org/hibernate/dialect/TestingDialects.java
core/trunk/core/src/test/java/org/hibernate/dialect/resolver/
core/trunk/core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java
core/trunk/core/src/test/java/org/hibernate/dialect/resolver/DialectResolverTest.java
core/trunk/core/src/test/resources/
core/trunk/core/src/test/resources/log4j.properties
Removed:
core/trunk/core/src/main/java/org/hibernate/dialect/DialectFactory.java
Modified:
core/trunk/core/src/main/java/org/hibernate/cfg/Environment.java
core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
Log:
HHH-2293 : DialectResolver
Modified: core/trunk/core/src/main/java/org/hibernate/cfg/Environment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Environment.java 2008-10-13 15:16:21 UTC (rev 15342)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Environment.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -240,7 +240,14 @@
* Hibernate SQL {@link org.hibernate.dialect.Dialect} class
*/
public static final String DIALECT ="hibernate.dialect";
+
/**
+ * {@link org.hibernate.dialect.resolver.DialectResolver} classes to register with the
+ * {@link org.hibernate.dialect.resolver.DialectFactory}
+ */
+ public static final String DIALECT_RESOLVERS = "hibernate.dialect_resolvers";
+
+ /**
* A default database schema (owner) name to use for unqualified tablenames
*/
public static final String DEFAULT_SCHEMA = "hibernate.default_schema";
Modified: core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java 2008-10-13 15:16:21 UTC (rev 15342)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -25,7 +25,6 @@
package org.hibernate.cfg;
import java.io.Serializable;
-import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
@@ -47,7 +46,7 @@
import org.hibernate.connection.ConnectionProvider;
import org.hibernate.connection.ConnectionProviderFactory;
import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.DialectFactory;
+import org.hibernate.dialect.resolver.DialectFactory;
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.exception.SQLExceptionConverterFactory;
import org.hibernate.hql.QueryTranslatorFactory;
@@ -64,23 +63,24 @@
import org.hibernate.util.StringHelper;
/**
- * Reads configuration properties and configures a <tt>Settings</tt> instance.
+ * Reads configuration properties and builds a {@link Settings} instance.
*
* @author Gavin King
*/
public class SettingsFactory implements Serializable {
+ private static final Logger log = LoggerFactory.getLogger( SettingsFactory.class );
+ private static final long serialVersionUID = -1194386144994524825L;
public static final String DEF_CACHE_REG_FACTORY = NoCachingRegionFactory.class.getName();
- private static final Logger log = LoggerFactory.getLogger(SettingsFactory.class);
protected SettingsFactory() {
}
-
+
public Settings buildSettings(Properties props) {
Settings settings = new Settings();
-
+
//SessionFactory name:
-
+
String sessionFactoryName = props.getProperty(Environment.SESSION_FACTORY_NAME);
settings.setSessionFactoryName(sessionFactoryName);
@@ -91,17 +91,17 @@
//Interrogate JDBC metadata
- String databaseName = null;
- int databaseMajorVersion = 0;
boolean metaSupportsScrollable = false;
boolean metaSupportsGetGeneratedKeys = false;
boolean metaSupportsBatchUpdates = false;
boolean metaReportsDDLCausesTxnCommit = false;
boolean metaReportsDDLInTxnSupported = true;
+ Dialect dialect = null;
// 'hibernate.temp.use_jdbc_metadata_defaults' is a temporary magic value.
- // The need for it is intended to be alleviated with 3.3 developement, thus it is
+ // The need for it is intended to be alleviated with future developement, thus it is
// not defined as an Environment constant...
+ //
// it is used to control whether we should consult the JDBC metadata to determine
// certain Settings default values; it is useful to *not* do this when the database
// may not be available (mainly in tools usage).
@@ -111,46 +111,48 @@
Connection conn = connections.getConnection();
try {
DatabaseMetaData meta = conn.getMetaData();
- databaseName = meta.getDatabaseProductName();
- databaseMajorVersion = getDatabaseMajorVersion(meta);
- log.info("RDBMS: " + databaseName + ", version: " + meta.getDatabaseProductVersion() );
- log.info("JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion() );
+ log.info( "RDBMS: " + meta.getDatabaseProductName() + ", version: " + meta.getDatabaseProductVersion() );
+ log.info( "JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion() );
- metaSupportsScrollable = meta.supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE);
+ dialect = DialectFactory.buildDialect( props, conn );
+
+ metaSupportsScrollable = meta.supportsResultSetType( ResultSet.TYPE_SCROLL_INSENSITIVE );
metaSupportsBatchUpdates = meta.supportsBatchUpdates();
metaReportsDDLCausesTxnCommit = meta.dataDefinitionCausesTransactionCommit();
metaReportsDDLInTxnSupported = !meta.dataDefinitionIgnoredInTransactions();
- metaSupportsGetGeneratedKeys = meta.supportsGetGeneratedKeys();
+ metaSupportsGetGeneratedKeys = meta.supportsGetGeneratedKeys();
}
- catch (SQLException sqle) {
- log.warn("Could not obtain connection metadata", sqle);
+ catch ( SQLException sqle ) {
+ log.warn( "Could not obtain connection metadata", sqle );
}
finally {
- connections.closeConnection(conn);
+ connections.closeConnection( conn );
}
}
- catch (SQLException sqle) {
- log.warn("Could not obtain connection to query metadata", sqle);
+ catch ( SQLException sqle ) {
+ log.warn( "Could not obtain connection to query metadata", sqle );
+ dialect = DialectFactory.buildDialect( props );
}
- catch (UnsupportedOperationException uoe) {
+ catch ( UnsupportedOperationException uoe ) {
// user supplied JDBC connections
+ dialect = DialectFactory.buildDialect( props );
}
}
+ else {
+ dialect = DialectFactory.buildDialect( props );
+ }
+
settings.setDataDefinitionImplicitCommit( metaReportsDDLCausesTxnCommit );
settings.setDataDefinitionInTransactionSupported( metaReportsDDLInTxnSupported );
+ settings.setDialect( dialect );
-
- //SQL Dialect:
- Dialect dialect = determineDialect( props, databaseName, databaseMajorVersion );
- settings.setDialect(dialect);
-
//use dialect default properties
final Properties properties = new Properties();
properties.putAll( dialect.getDefaultProperties() );
- properties.putAll(props);
-
+ properties.putAll( props );
+
// Transaction settings:
-
+
TransactionFactory transactionFactory = createTransactionFactory(properties);
settings.setTransactionFactory(transactionFactory);
settings.setTransactionManagerLookup( createTransactionManagerLookup(properties) );
@@ -173,7 +175,7 @@
if (batchSize>0) log.info("JDBC batch updates for versioned data: " + enabledDisabled(jdbcBatchVersionedData) );
settings.setJdbcBatchVersionedData(jdbcBatchVersionedData);
settings.setBatcherFactory( createBatcherFactory(properties, batchSize) );
-
+
boolean useScrollableResultSets = PropertiesHelper.getBoolean(Environment.USE_SCROLLABLE_RESULTSET, properties, metaSupportsScrollable);
log.info("Scrollable result sets: " + enabledDisabled(useScrollableResultSets) );
settings.setScrollableResultSetsEnabled(useScrollableResultSets);
@@ -224,7 +226,7 @@
boolean comments = PropertiesHelper.getBoolean(Environment.USE_SQL_COMMENTS, properties);
log.info( "Generate SQL with comments: " + enabledDisabled(comments) );
settings.setCommentsEnabled(comments);
-
+
boolean orderUpdates = PropertiesHelper.getBoolean(Environment.ORDER_UPDATES, properties);
log.info( "Order SQL updates by primary key: " + enabledDisabled(orderUpdates) );
settings.setOrderUpdatesEnabled(orderUpdates);
@@ -232,9 +234,9 @@
boolean orderInserts = PropertiesHelper.getBoolean(Environment.ORDER_INSERTS, properties);
log.info( "Order SQL inserts for batching: " + enabledDisabled( orderInserts ) );
settings.setOrderInsertsEnabled( orderInserts );
-
+
//Query parser settings:
-
+
settings.setQueryTranslatorFactory( createQueryTranslatorFactory(properties) );
Map querySubstitutions = PropertiesHelper.toMap(Environment.QUERY_SUBSTITUTIONS, " ,=;:\n\t\r\f", properties);
@@ -244,7 +246,7 @@
boolean jpaqlCompliance = PropertiesHelper.getBoolean( Environment.JPAQL_STRICT_COMPLIANCE, properties, false );
settings.setStrictJPAQLCompliance( jpaqlCompliance );
log.info( "JPA-QL strict compliance: " + enabledDisabled( jpaqlCompliance ) );
-
+
// Second-level / query cache:
boolean useSecondLevelCache = PropertiesHelper.getBoolean(Environment.USE_SECOND_LEVEL_CACHE, properties, true);
@@ -275,9 +277,9 @@
settings.setStructuredCacheEntriesEnabled(useStructuredCacheEntries);
if (useQueryCache) settings.setQueryCacheFactory( createQueryCacheFactory(properties) );
-
+
//SQL Exception converter:
-
+
SQLExceptionConverter sqlExceptionConverter;
try {
sqlExceptionConverter = SQLExceptionConverterFactory.buildSQLExceptionConverter( dialect, properties );
@@ -302,13 +304,13 @@
boolean useStatistics = PropertiesHelper.getBoolean(Environment.GENERATE_STATISTICS, properties);
log.info( "Statistics: " + enabledDisabled(useStatistics) );
settings.setStatisticsEnabled(useStatistics);
-
+
boolean useIdentifierRollback = PropertiesHelper.getBoolean(Environment.USE_IDENTIFIER_ROLLBACK, properties);
log.info( "Deleted entity synthetic identifier rollback: " + enabledDisabled(useIdentifierRollback) );
settings.setIdentifierRollbackEnabled(useIdentifierRollback);
-
+
//Schema export:
-
+
String autoSchemaExport = properties.getProperty(Environment.HBM2DDL_AUTO);
if ( "validate".equals(autoSchemaExport) ) settings.setAutoValidateSchema(true);
if ( "update".equals(autoSchemaExport) ) settings.setAutoUpdateSchema(true);
@@ -348,24 +350,10 @@
}
}
- private int getDatabaseMajorVersion(DatabaseMetaData meta) {
- try {
- Method gdbmvMethod = DatabaseMetaData.class.getMethod("getDatabaseMajorVersion", null);
- return ( (Integer) gdbmvMethod.invoke(meta, null) ).intValue();
- }
- catch (NoSuchMethodException nsme) {
- return 0;
- }
- catch (Throwable t) {
- log.debug("could not get database version from JDBC metadata");
- return 0;
- }
- }
-
private static String enabledDisabled(boolean value) {
return value ? "enabled" : "disabled";
}
-
+
protected QueryCacheFactory createQueryCacheFactory(Properties properties) {
String queryCacheFactoryClassName = PropertiesHelper.getString(
Environment.QUERY_CACHE_FACTORY, properties, "org.hibernate.cache.StandardQueryCacheFactory"
@@ -401,7 +389,7 @@
throw new HibernateException( "could not instantiate RegionFactory [" + regionFactoryClassName + "]", e );
}
}
-
+
protected QueryTranslatorFactory createQueryTranslatorFactory(Properties properties) {
String className = PropertiesHelper.getString(
Environment.QUERY_TRANSLATOR, properties, "org.hibernate.hql.ast.ASTQueryTranslatorFactory"
@@ -414,7 +402,7 @@
throw new HibernateException("could not instantiate QueryTranslatorFactory: " + className, cnfe);
}
}
-
+
protected BatcherFactory createBatcherFactory(Properties properties, int batchSize) {
String batcherClass = properties.getProperty(Environment.BATCH_STRATEGY);
if (batcherClass==null) {
@@ -432,21 +420,17 @@
}
}
}
-
+
protected ConnectionProvider createConnectionProvider(Properties properties) {
return ConnectionProviderFactory.newConnectionProvider(properties);
}
-
+
protected TransactionFactory createTransactionFactory(Properties properties) {
return TransactionFactoryFactory.buildTransactionFactory(properties);
}
-
+
protected TransactionManagerLookup createTransactionManagerLookup(Properties properties) {
- return TransactionManagerLookupFactory.getTransactionManagerLookup(properties);
+ return TransactionManagerLookupFactory.getTransactionManagerLookup(properties);
}
- private Dialect determineDialect(Properties props, String databaseName, int databaseMajorVersion) {
- return DialectFactory.buildDialect( props, databaseName, databaseMajorVersion );
- }
-
}
Deleted: core/trunk/core/src/main/java/org/hibernate/dialect/DialectFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/DialectFactory.java 2008-10-13 15:16:21 UTC (rev 15342)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/DialectFactory.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -1,179 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- *
- */
-package org.hibernate.dialect;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * A factory for generating Dialect instances.
- *
- * @author Steve Ebersole
- */
-public class DialectFactory {
-
- /**
- * Builds an appropriate Dialect instance.
- * <p/>
- * If a dialect is explicitly named in the incoming properties, it is used. Otherwise, the database name and version
- * (obtained from connection metadata) are used to make the dertemination.
- * <p/>
- * An exception is thrown if a dialect was not explicitly set and the database name is not known.
- *
- * @param props The configuration properties.
- * @param databaseName The name of the database product (obtained from metadata).
- * @param databaseMajorVersion The major version of the database product (obtained from metadata).
- *
- * @return The appropriate dialect.
- *
- * @throws HibernateException No dialect specified and database name not known.
- */
- public static Dialect buildDialect(Properties props, String databaseName, int databaseMajorVersion)
- throws HibernateException {
- String dialectName = props.getProperty( Environment.DIALECT );
- if ( dialectName == null ) {
- return determineDialect( databaseName, databaseMajorVersion );
- }
- else {
- return buildDialect( dialectName );
- }
- }
-
- /**
- * Determine the appropriate Dialect to use given the database product name
- * and major version.
- *
- * @param databaseName The name of the database product (obtained from metadata).
- * @param databaseMajorVersion The major version of the database product (obtained from metadata).
- *
- * @return An appropriate dialect instance.
- */
- public static Dialect determineDialect(String databaseName, int databaseMajorVersion) {
- if ( databaseName == null ) {
- throw new HibernateException( "Hibernate Dialect must be explicitly set" );
- }
-
- DatabaseDialectMapper mapper = ( DatabaseDialectMapper ) MAPPERS.get( databaseName );
- if ( mapper == null ) {
- throw new HibernateException( "Hibernate Dialect must be explicitly set for database: " + databaseName );
- }
-
- String dialectName = mapper.getDialectClass( databaseMajorVersion );
- return buildDialect( dialectName );
- }
-
- /**
- * Returns a dialect instance given the name of the class to use.
- *
- * @param dialectName The name of the dialect class.
- *
- * @return The dialect instance.
- */
- public static Dialect buildDialect(String dialectName) {
- try {
- return ( Dialect ) ReflectHelper.classForName( dialectName ).newInstance();
- }
- catch ( ClassNotFoundException cnfe ) {
- throw new HibernateException( "Dialect class not found: " + dialectName );
- }
- catch ( Exception e ) {
- throw new HibernateException( "Could not instantiate dialect class", e );
- }
- }
-
- /**
- * For a given database product name, instances of
- * DatabaseDialectMapper know which Dialect to use for different versions.
- */
- public static interface DatabaseDialectMapper {
- public String getDialectClass(int majorVersion);
- }
-
- /**
- * A simple DatabaseDialectMapper for dialects which are independent
- * of the underlying database product version.
- */
- public static class VersionInsensitiveMapper implements DatabaseDialectMapper {
- private String dialectClassName;
-
- public VersionInsensitiveMapper(String dialectClassName) {
- this.dialectClassName = dialectClassName;
- }
-
- public String getDialectClass(int majorVersion) {
- return dialectClassName;
- }
- }
-
- // TODO : this is the stuff it'd be nice to move to a properties file or some other easily user-editable place
- private static final Map MAPPERS = new HashMap();
- static {
- // detectors...
- MAPPERS.put( "HSQL Database Engine", new VersionInsensitiveMapper( "org.hibernate.dialect.HSQLDialect" ) );
- MAPPERS.put( "H2", new VersionInsensitiveMapper( "org.hibernate.dialect.H2Dialect" ) );
- MAPPERS.put( "MySQL", new VersionInsensitiveMapper( "org.hibernate.dialect.MySQLDialect" ) );
- MAPPERS.put( "PostgreSQL", new VersionInsensitiveMapper( "org.hibernate.dialect.PostgreSQLDialect" ) );
- MAPPERS.put( "Apache Derby", new VersionInsensitiveMapper( "org.hibernate.dialect.DerbyDialect" ) );
-
- MAPPERS.put( "Ingres", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
- MAPPERS.put( "ingres", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
- MAPPERS.put( "INGRES", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
-
- MAPPERS.put( "Microsoft SQL Server Database", new VersionInsensitiveMapper( "org.hibernate.dialect.SQLServerDialect" ) );
- MAPPERS.put( "Microsoft SQL Server", new VersionInsensitiveMapper( "org.hibernate.dialect.SQLServerDialect" ) );
- MAPPERS.put( "Sybase SQL Server", new VersionInsensitiveMapper( "org.hibernate.dialect.SybaseDialect" ) );
- MAPPERS.put( "Adaptive Server Enterprise", new VersionInsensitiveMapper( "org.hibernate.dialect.SybaseDialect" ) );
-
- MAPPERS.put( "Informix Dynamic Server", new VersionInsensitiveMapper( "org.hibernate.dialect.InformixDialect" ) );
-
- // thanks goodness for "universal" databases...
- MAPPERS.put( "DB2/NT", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
- MAPPERS.put( "DB2/LINUX", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
- MAPPERS.put( "DB2/6000", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
- MAPPERS.put( "DB2/HPUX", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
- MAPPERS.put( "DB2/SUN", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
- MAPPERS.put( "DB2/LINUX390", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
- MAPPERS.put( "DB2/AIX64", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
-
- MAPPERS.put(
- "Oracle",
- new DatabaseDialectMapper() {
- public String getDialectClass(int majorVersion) {
- switch ( majorVersion ) {
- case 8: return Oracle8iDialect.class.getName();
- case 9: return Oracle9iDialect.class.getName();
- case 10: return Oracle10gDialect.class.getName();
- default: throw new HibernateException( "unknown Oracle major version [" + majorVersion + "]" );
- }
- }
- }
- );
- }
-}
Added: core/trunk/core/src/main/java/org/hibernate/dialect/resolver/AbstractDialectResolver.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/resolver/AbstractDialectResolver.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/resolver/AbstractDialectResolver.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -0,0 +1,80 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.exception.JDBCConnectionException;
+import org.hibernate.JDBCException;
+
+/**
+ * A templated resolver impl which delegates to the {@link #resolveDialectInternal} method
+ * and handles any thrown {@link SQLException}s.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractDialectResolver implements DialectResolver {
+ private static final Logger log = LoggerFactory.getLogger( AbstractDialectResolver.class );
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here we template the resolution, delegating to {@link #resolveDialectInternal} and handling
+ * {@link java.sql.SQLException}s properly.
+ */
+ public final Dialect resolveDialect(DatabaseMetaData metaData) {
+ try {
+ return resolveDialectInternal( metaData );
+ }
+ catch ( SQLException sqlException ) {
+ JDBCException jdbcException = BasicSQLExceptionConverter.INSTANCE.convert( sqlException );
+ if ( jdbcException instanceof JDBCConnectionException ) {
+ throw jdbcException;
+ }
+ else {
+ log.warn( BasicSQLExceptionConverter.MSG + " : " + sqlException.getMessage() );
+ return null;
+ }
+ }
+ catch ( Throwable t ) {
+ log.warn( "Error executing resolver [" + this + "] : " + t.getMessage() );
+ return null;
+ }
+ }
+
+ /**
+ * Perform the actual resolution without caring about handling {@link SQLException}s.
+ *
+ * @param metaData The database metadata
+ * @return The resolved dialect, or null if we could not resolve.
+ * @throws SQLException Indicates problems accessing the metadata.
+ */
+ protected abstract Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException;
+}
Added: core/trunk/core/src/main/java/org/hibernate/dialect/resolver/BasicDialectResolver.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/resolver/BasicDialectResolver.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/resolver/BasicDialectResolver.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -0,0 +1,78 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.HibernateException;
+
+/**
+ * Intended as support for custom resolvers.
+ *
+ * @author Steve Ebersole
+ */
+public class BasicDialectResolver extends AbstractDialectResolver {
+ public static final int VERSION_INSENSITIVE_VERSION = -9999;
+
+ private final String matchingName;
+ private final int matchingVersion;
+ private final Class dialectClass;
+
+ public BasicDialectResolver(String matchingName, Class dialectClass) {
+ this( matchingName, VERSION_INSENSITIVE_VERSION, dialectClass );
+ }
+
+ public BasicDialectResolver(String matchingName, int matchingVersion, Class dialectClass) {
+ this.matchingName = matchingName;
+ this.matchingVersion = matchingVersion;
+ this.dialectClass = dialectClass;
+ }
+
+ protected final Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
+ final String databaseName = metaData.getDatabaseProductName();
+ final int databaseMajorVersion = metaData.getDatabaseMajorVersion();
+
+ if ( matchingName.equalsIgnoreCase( databaseName )
+ && ( matchingVersion == VERSION_INSENSITIVE_VERSION || matchingVersion == databaseMajorVersion ) ) {
+ try {
+ return ( Dialect ) dialectClass.newInstance();
+ }
+ catch ( HibernateException e ) {
+ // conceivable that the dialect ctor could throw HibernateExceptions, so don't re-wrap
+ throw e;
+ }
+ catch ( Throwable t ) {
+ throw new HibernateException(
+ "Could not instantiate specified Dialect class [" + dialectClass.getName() + "]",
+ t
+ );
+ }
+ }
+
+ return null;
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/dialect/resolver/BasicSQLExceptionConverter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/resolver/BasicSQLExceptionConverter.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/resolver/BasicSQLExceptionConverter.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -0,0 +1,62 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.SQLException;
+
+import org.hibernate.exception.SQLStateConverter;
+import org.hibernate.exception.ViolatedConstraintNameExtracter;
+import org.hibernate.JDBCException;
+
+/**
+ * A helper to centralize conversion of {@link java.sql.SQLException}s to {@link org.hibernate.JDBCException}s.
+ *
+ * @author Steve Ebersole
+ */
+public class BasicSQLExceptionConverter {
+ public static final BasicSQLExceptionConverter INSTANCE = new BasicSQLExceptionConverter();
+ public static final String MSG = "Unable to query java.sql.DatabaseMetaData";
+
+ private static final SQLStateConverter CONVERTER = new SQLStateConverter( new ConstraintNameExtracter() );
+
+ /**
+ * Perform a conversion.
+ *
+ * @param sqlException The exception to convert.
+ * @return The converted exception.
+ */
+ public JDBCException convert(SQLException sqlException) {
+ return CONVERTER.convert( sqlException, MSG, null );
+ }
+
+ private static class ConstraintNameExtracter implements ViolatedConstraintNameExtracter {
+ /**
+ * {@inheritDoc}
+ */
+ public String extractConstraintName(SQLException sqle) {
+ return "???";
+ }
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -0,0 +1,166 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.DatabaseMetaData;
+import java.util.Properties;
+
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.resolver.DialectResolver;
+import org.hibernate.dialect.resolver.DialectResolverSet;
+import org.hibernate.dialect.resolver.StandardDialectResolver;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.cfg.Environment;
+import org.hibernate.util.ReflectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A factory for generating Dialect instances.
+ *
+ * @author Steve Ebersole
+ * @author Tomoto Shimizu Washio
+ */
+public class DialectFactory {
+ private static final Logger log = LoggerFactory.getLogger( DialectFactory.class );
+
+ private static DialectResolverSet DIALECT_RESOLVERS = new DialectResolverSet();
+
+ static {
+ // register the standard dialect resolver
+ DIALECT_RESOLVERS.addResolver( new StandardDialectResolver() );
+
+ // register resolvers set via Environment property
+ String userSpecifedResolverSetting = Environment.getProperties().getProperty( Environment.DIALECT_RESOLVERS );
+ if ( userSpecifedResolverSetting != null ) {
+ String[] userSpecifedResolvers = userSpecifedResolverSetting.split( "\\s+" );
+ for ( int i = 0; i < userSpecifedResolvers.length; i++ ) {
+ registerDialectResolver( userSpecifedResolvers[i] );
+ }
+ }
+ }
+
+ /*package*/ static void registerDialectResolver(String resolverName) {
+ try {
+ DialectResolver resolver = ( DialectResolver ) ReflectHelper.classForName( resolverName ).newInstance();
+ DIALECT_RESOLVERS.addResolverAtFirst( resolver );
+ }
+ catch ( ClassNotFoundException cnfe ) {
+ log.warn( "Dialect resolver class not found: " + resolverName );
+ }
+ catch ( Exception e ) {
+ log.warn( "Could not instantiate dialect resolver class", e );
+ }
+ }
+
+ /**
+ * Builds an appropriate Dialect instance.
+ * <p/>
+ * If a dialect is explicitly named in the incoming properties, it is used. Otherwise, it is
+ * determined by dialect resolvers based on the passed connection.
+ * <p/>
+ * An exception is thrown if a dialect was not explicitly set and no resolver could make
+ * the determination from the given connection.
+ *
+ * @param properties The configuration properties.
+ * @param connection The configured connection.
+ * @return The appropriate dialect instance.
+ * @throws HibernateException No dialect specified and no resolver could make the determination.
+ */
+ public static Dialect buildDialect(Properties properties, Connection connection) throws HibernateException {
+ String dialectName = properties.getProperty( Environment.DIALECT );
+ if ( dialectName == null ) {
+ return determineDialect( connection );
+ }
+ else {
+ return constructDialect( dialectName );
+ }
+ }
+
+ public static Dialect buildDialect(Properties properties) {
+ String dialectName = properties.getProperty( Environment.DIALECT );
+ if ( dialectName == null ) {
+ throw new HibernateException( "'hibernate.dialect' must be set when no Connection avalable" );
+ }
+ return constructDialect( dialectName );
+ }
+
+ /**
+ * Determine the appropriate Dialect to use given the connection.
+ *
+ * @param connection The configured connection.
+ * @return The appropriate dialect instance.
+ *
+ * @throws HibernateException No connection given or no resolver could make
+ * the determination from the given connection.
+ */
+ private static Dialect determineDialect(Connection connection) {
+ if ( connection == null ) {
+ throw new HibernateException( "Connection cannot be null when 'hibernate.dialect' not set" );
+ }
+
+ try {
+ final DatabaseMetaData databaseMetaData = connection.getMetaData();
+ final Dialect dialect = DIALECT_RESOLVERS.resolveDialect( databaseMetaData );
+
+ if ( dialect == null ) {
+ throw new HibernateException(
+ "Unable to determine Dialect to use [name=" + databaseMetaData.getDatabaseProductName() +
+ ", majorVersion=" + databaseMetaData.getDatabaseMajorVersion() +
+ "]; user must register resolver or explicitly set 'hibernate.dialect'"
+ );
+ }
+
+ return dialect;
+ }
+ catch ( SQLException sqlException ) {
+ throw new HibernateException(
+ "Unable to access java.sql.DatabaseMetaData to determine appropriate Dialect to use",
+ sqlException
+ );
+ }
+ }
+
+ /**
+ * Returns a dialect instance given the name of the class to use.
+ *
+ * @param dialectName The name of the dialect class.
+ *
+ * @return The dialect instance.
+ */
+ public static Dialect constructDialect(String dialectName) {
+ try {
+ return ( Dialect ) ReflectHelper.classForName( dialectName ).newInstance();
+ }
+ catch ( ClassNotFoundException cnfe ) {
+ throw new HibernateException( "Dialect class not found: " + dialectName, cnfe );
+ }
+ catch ( Exception e ) {
+ throw new HibernateException( "Could not instantiate dialect class", e );
+ }
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/dialect/resolver/DialectResolver.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/resolver/DialectResolver.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/resolver/DialectResolver.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -0,0 +1,51 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.exception.JDBCConnectionException;
+
+/**
+ * Contract for determining the {@link Dialect} to use based on a JDBC {@link Connection}.
+ *
+ * @author Tomoto Shimizu Washio
+ * @author Steve Ebersole
+ */
+public interface DialectResolver {
+ /**
+ * Determine the {@link Dialect} to use based on the given JDBC {@link DatabaseMetaData}. Implementations are
+ * expected to return the {@link Dialect} instance to use, or null if the {@link DatabaseMetaData} does not match
+ * the criteria handled by this impl.
+ *
+ * @param metaData The JDBC metadata.
+ * @return The dialect to use, or null.
+ * @throws JDBCConnectionException Indicates a 'non transient connection problem', which indicates that
+ * we should stop resolution attempts.
+ */
+ public Dialect resolveDialect(DatabaseMetaData metaData) throws JDBCConnectionException;
+}
Added: core/trunk/core/src/main/java/org/hibernate/dialect/resolver/DialectResolverSet.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/resolver/DialectResolverSet.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/resolver/DialectResolverSet.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -0,0 +1,92 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.DatabaseMetaData;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.exception.JDBCConnectionException;
+
+/**
+ * A {@link DialectResolver} implementation which coordinates resolution by delegating to its
+ * registered sub-resolvers. Sub-resolvers may be registered by calling either {@link #addResolver} or
+ * {@link #addResolverAtFirst}.
+ *
+ * @author Tomoto Shimizu Washio
+ */
+public class DialectResolverSet implements DialectResolver {
+ private static Logger log = LoggerFactory.getLogger( DialectResolverSet.class );
+
+ private List resolvers = new ArrayList();
+
+ /**
+ * {@inheritDoc}
+ */
+ public Dialect resolveDialect(DatabaseMetaData metaData) {
+ Iterator i = resolvers.iterator();
+ while ( i.hasNext() ) {
+ final DialectResolver resolver = ( DialectResolver ) i.next();
+ try {
+ Dialect dialect = resolver.resolveDialect( metaData );
+ if ( dialect != null ) {
+ return dialect;
+ }
+ }
+ catch ( JDBCConnectionException e ) {
+ throw e;
+ }
+ catch ( Throwable t ) {
+ log.info( "sub-resolver threw unexpected exception, continuing to next : " + t.getMessage() );
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Add a resolver at the end of the underlying resolver list. The resolver added by this method is at lower
+ * priority than any other existing resolvers.
+ *
+ * @param resolver The resolver to add.
+ */
+ public void addResolver(DialectResolver resolver) {
+ resolvers.add( resolver );
+ }
+
+ /**
+ * Add a resolver at the beginning of the underlying resolver list. The resolver added by this method is at higher
+ * priority than any other existing resolvers.
+ *
+ * @param resolver The resolver to add.
+ */
+ public void addResolverAtFirst(DialectResolver resolver) {
+ resolvers.add( 0, resolver );
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/dialect/resolver/StandardDialectResolver.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/resolver/StandardDialectResolver.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/resolver/StandardDialectResolver.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -0,0 +1,118 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.HSQLDialect;
+import org.hibernate.dialect.H2Dialect;
+import org.hibernate.dialect.MySQLDialect;
+import org.hibernate.dialect.PostgreSQLDialect;
+import org.hibernate.dialect.DerbyDialect;
+import org.hibernate.dialect.IngresDialect;
+import org.hibernate.dialect.SQLServerDialect;
+import org.hibernate.dialect.SybaseDialect;
+import org.hibernate.dialect.InformixDialect;
+import org.hibernate.dialect.DB2Dialect;
+import org.hibernate.dialect.Oracle10gDialect;
+import org.hibernate.dialect.Oracle9iDialect;
+import org.hibernate.dialect.Oracle8iDialect;
+
+/**
+ * The standard Hibernate resolver.
+ *
+ * @author Steve Ebersole
+ */
+public class StandardDialectResolver extends AbstractDialectResolver{
+ private static final Logger log = LoggerFactory.getLogger( StandardDialectResolver.class );
+
+ protected Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
+ String databaseName = metaData.getDatabaseProductName();
+ int databaseMajorVersion = metaData.getDatabaseMajorVersion();
+
+ if ( "HSQL Database Engine".equals( databaseName ) ) {
+ return new HSQLDialect();
+ }
+
+ if ( "H2".equals( databaseName ) ) {
+ return new H2Dialect();
+ }
+
+ if ( "MySQL".equals( databaseName ) ) {
+ return new MySQLDialect();
+ }
+
+ if ( "PostgreSQL".equals( databaseName ) ) {
+ return new PostgreSQLDialect();
+ }
+
+ if ( "Apache Derby".equals( databaseName ) ) {
+ return new DerbyDialect();
+ }
+
+ if ( "ingres".equalsIgnoreCase( databaseName ) ) {
+ return new IngresDialect();
+ }
+
+ if ( databaseName.startsWith( "Microsoft SQL Server" ) ) {
+ return new SQLServerDialect();
+ }
+
+ if ( "Sybase SQL Server".equals( databaseName ) || "Adaptive Server Enterprise".equals( databaseName ) ) {
+ return new SybaseDialect();
+ }
+
+ if ( "Informix Dynamic Server".equals( databaseName ) ) {
+ return new InformixDialect();
+ }
+
+ if ( databaseName.startsWith( "DB2/" ) ) {
+ return new DB2Dialect();
+ }
+
+ if ( "Oracle".equals( databaseName ) ) {
+ switch ( databaseMajorVersion ) {
+ case 11:
+ log.warn( "Oracle 11g is not yet fully supported; using 10g dialect" );
+ return new Oracle10gDialect();
+ case 10:
+ return new Oracle10gDialect();
+ case 9:
+ return new Oracle9iDialect();
+ case 8:
+ return new Oracle8iDialect();
+ default:
+ log.warn( "unknown Oracle major version [" + databaseMajorVersion + "]" );
+ }
+ }
+
+ return null;
+ }
+}
Added: core/trunk/core/src/test/java/org/hibernate/dialect/Mocks.java
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/dialect/Mocks.java (rev 0)
+++ core/trunk/core/src/test/java/org/hibernate/dialect/Mocks.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -0,0 +1,148 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.SQLException;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class Mocks {
+
+ public static Connection createConnection(String dbName, int version) {
+ DatabaseMetaDataHandler metadataHandler = new DatabaseMetaDataHandler( dbName, version );
+ ConnectionHandler connectionHandler = new ConnectionHandler();
+
+ DatabaseMetaData metadataProxy = ( DatabaseMetaData ) Proxy.newProxyInstance(
+ ClassLoader.getSystemClassLoader(),
+ new Class[] { DatabaseMetaData.class },
+ metadataHandler
+ );
+
+ Connection connectionProxy = ( Connection ) Proxy.newProxyInstance(
+ ClassLoader.getSystemClassLoader(),
+ new Class[] { Connection.class },
+ connectionHandler
+ );
+
+ metadataHandler.setConnectionProxy( connectionProxy );
+ connectionHandler.setMetadataProxy( metadataProxy );
+
+ return connectionProxy;
+ }
+
+ private static class ConnectionHandler implements InvocationHandler {
+ private DatabaseMetaData metadataProxy;
+
+ public void setMetadataProxy(DatabaseMetaData metadataProxy) {
+ this.metadataProxy = metadataProxy;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ final String methodName = method.getName();
+ if ( "getMetaData".equals( methodName ) ) {
+ return metadataProxy;
+ }
+
+ if ( "toString".equals( methodName ) ) {
+ return "Connection proxy [@" + hashCode() + "]";
+ }
+
+ if ( "hashCode".equals( methodName ) ) {
+ return new Integer( this.hashCode() );
+ }
+
+ if ( canThrowSQLException( method ) ) {
+ throw new SQLException();
+ }
+ else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ private static class DatabaseMetaDataHandler implements InvocationHandler {
+ private final String databaseName;
+ private final int majorVersion;
+
+ private Connection connectionProxy;
+
+ public void setConnectionProxy(Connection connectionProxy) {
+ this.connectionProxy = connectionProxy;
+ }
+
+ private DatabaseMetaDataHandler(String databaseName, int majorVersion) {
+ this.databaseName = databaseName;
+ this.majorVersion = majorVersion;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ final String methodName = method.getName();
+ if ( "getDatabaseProductName".equals( methodName ) ) {
+ return databaseName;
+ }
+
+ if ( "getDatabaseMajorVersion".equals( methodName ) ) {
+ return new Integer( majorVersion );
+ }
+
+ if ( "getConnection".equals( methodName ) ) {
+ return connectionProxy;
+ }
+
+ if ( "toString".equals( methodName ) ) {
+ return "DatabaseMetaData proxy [db-name=" + databaseName + ", version=" + majorVersion + "]";
+ }
+
+ if ( "hashCode".equals( methodName ) ) {
+ return new Integer( this.hashCode() );
+ }
+
+ if ( canThrowSQLException( method ) ) {
+ throw new SQLException();
+ }
+ else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ private static boolean canThrowSQLException(Method method) {
+ final Class[] exceptions = method.getExceptionTypes();
+ for ( int i = 0; i < exceptions.length; i++ ) {
+ if ( SQLException.class.isAssignableFrom( exceptions[i] ) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
Added: core/trunk/core/src/test/java/org/hibernate/dialect/TestingDialects.java
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/dialect/TestingDialects.java (rev 0)
+++ core/trunk/core/src/test/java/org/hibernate/dialect/TestingDialects.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -0,0 +1,109 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect;
+
+import java.sql.SQLException;
+import java.sql.DatabaseMetaData;
+
+import org.hibernate.dialect.resolver.AbstractDialectResolver;
+import org.hibernate.dialect.resolver.BasicDialectResolver;
+import org.hibernate.HibernateException;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class TestingDialects {
+
+ public static class MyDialect1 extends Dialect {
+ }
+
+ public static class MyDialect21 extends Dialect {
+ }
+
+ public static class MyDialect22 extends Dialect {
+ }
+
+ public static class MySpecialDB2Dialect extends Dialect {
+ }
+
+ public static class MyDialectResolver1 extends AbstractDialectResolver {
+ protected Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
+ String databaseName = metaData.getDatabaseProductName();
+ int databaseMajorVersion = metaData.getDatabaseMajorVersion();
+ if ( "MyDatabase1".equals( databaseName ) ) {
+ return new MyDialect1();
+ }
+ if ( "MyDatabase2".equals( databaseName ) ) {
+ if ( databaseMajorVersion >= 2 ) {
+ return new MyDialect22();
+ }
+ if ( databaseMajorVersion >= 1 ) {
+ return new MyDialect21();
+ }
+ }
+ return null;
+ }
+ }
+
+ public static class MyDialectResolver2 extends BasicDialectResolver {
+ public MyDialectResolver2() {
+ super( "MyTrickyDatabase1", MyDialect1.class );
+ }
+ }
+
+ public static class ErrorDialectResolver1 extends AbstractDialectResolver {
+ public Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
+ String databaseName = metaData.getDatabaseProductName();
+ if ( databaseName.equals( "ConnectionErrorDatabase1" ) ) {
+ throw new SQLException( "Simulated connection error", "08001" );
+ }
+ else {
+ throw new SQLException();
+ }
+ }
+ }
+
+ public static class ErrorDialectResolver2 extends AbstractDialectResolver {
+ public Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
+ String databaseName = metaData.getDatabaseProductName();
+ if ( databaseName.equals( "ErrorDatabase1" ) ) {
+ throw new SQLException();
+ }
+ if ( databaseName.equals( "ErrorDatabase2" ) ) {
+ throw new HibernateException( "This is a trap!" );
+ }
+ return null;
+ }
+ }
+
+ public static class MyOverridingDialectResolver1 extends BasicDialectResolver {
+ public MyOverridingDialectResolver1() {
+ super( "DB2/MySpecialPlatform", MySpecialDB2Dialect.class );
+ }
+ }
+
+}
Added: core/trunk/core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java (rev 0)
+++ core/trunk/core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -0,0 +1,187 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.util.Properties;
+import java.sql.Connection;
+
+import junit.framework.TestSuite;
+import junit.framework.TestCase;
+import junit.framework.Test;
+
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.resolver.DialectFactory;
+import org.hibernate.dialect.HSQLDialect;
+import org.hibernate.dialect.H2Dialect;
+import org.hibernate.dialect.MySQLDialect;
+import org.hibernate.dialect.PostgreSQLDialect;
+import org.hibernate.dialect.DerbyDialect;
+import org.hibernate.dialect.IngresDialect;
+import org.hibernate.dialect.SQLServerDialect;
+import org.hibernate.dialect.SybaseDialect;
+import org.hibernate.dialect.InformixDialect;
+import org.hibernate.dialect.DB2Dialect;
+import org.hibernate.dialect.Oracle8iDialect;
+import org.hibernate.dialect.Oracle9iDialect;
+import org.hibernate.dialect.Oracle10gDialect;
+import org.hibernate.dialect.TestingDialects;
+import org.hibernate.dialect.Mocks;
+import org.hibernate.cfg.Environment;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class DialectFactoryTest extends TestCase {
+ public DialectFactoryTest(String name) {
+ super( name );
+ }
+
+ public static Test suite() {
+ return new TestSuite( DialectFactoryTest.class );
+ }
+
+ public void testBuildDialectByClass() {
+ assertEquals(
+ HSQLDialect.class,
+ DialectFactory.constructDialect( "org.hibernate.dialect.HSQLDialect" ).getClass()
+ );
+
+ try {
+ DialectFactory.constructDialect( "org.hibernate.dialect.NoSuchDialect" );
+ fail();
+ }
+ catch ( HibernateException e ) {
+ assertEquals( "unexpected exception type", e.getCause().getClass(), ClassNotFoundException.class );
+ }
+
+ try {
+ DialectFactory.constructDialect( "java.lang.Object" );
+ fail();
+ }
+ catch ( HibernateException e ) {
+ assertEquals( "unexpected exception type", e.getCause().getClass(), ClassCastException.class );
+ }
+ }
+
+ public void testBuildDialectByProperties() {
+ Properties props = new Properties();
+
+ try {
+ DialectFactory.buildDialect( props, null );
+ fail();
+ }
+ catch ( HibernateException e ) {
+ assertNull( e.getCause() );
+ }
+
+ props.setProperty( Environment.DIALECT, "org.hibernate.dialect.HSQLDialect" );
+ assertTrue( DialectFactory.buildDialect( props, null ) instanceof HSQLDialect );
+ }
+
+ public void testPreregisteredDialects() {
+ testDetermination( "HSQL Database Engine", HSQLDialect.class );
+ testDetermination( "H2", H2Dialect.class );
+ testDetermination( "MySQL", MySQLDialect.class );
+ testDetermination( "PostgreSQL", PostgreSQLDialect.class );
+ testDetermination( "Apache Derby", DerbyDialect.class );
+ testDetermination( "Ingres", IngresDialect.class );
+ testDetermination( "ingres", IngresDialect.class );
+ testDetermination( "INGRES", IngresDialect.class );
+ testDetermination( "Microsoft SQL Server Database", SQLServerDialect.class );
+ testDetermination( "Microsoft SQL Server", SQLServerDialect.class );
+ testDetermination( "Sybase SQL Server", SybaseDialect.class );
+ testDetermination( "Adaptive Server Enterprise", SybaseDialect.class );
+ testDetermination( "Informix Dynamic Server", InformixDialect.class );
+ testDetermination( "DB2/NT", DB2Dialect.class );
+ testDetermination( "DB2/LINUX", DB2Dialect.class );
+ testDetermination( "DB2/6000", DB2Dialect.class );
+ testDetermination( "DB2/HPUX", DB2Dialect.class );
+ testDetermination( "DB2/SUN", DB2Dialect.class );
+ testDetermination( "DB2/LINUX390", DB2Dialect.class );
+ testDetermination( "DB2/AIX64", DB2Dialect.class );
+ testDetermination( "Oracle", 8, Oracle8iDialect.class );
+ testDetermination( "Oracle", 9, Oracle9iDialect.class );
+ testDetermination( "Oracle", 10, Oracle10gDialect.class );
+ testDetermination( "Oracle", 11, Oracle10gDialect.class );
+ }
+
+ public void testCustomDialects() {
+ DialectFactory.registerDialectResolver( TestingDialects.MyDialectResolver1.class.getName() );
+ DialectFactory.registerDialectResolver( TestingDialects.MyDialectResolver2.class.getName() );
+ DialectFactory.registerDialectResolver( TestingDialects.ErrorDialectResolver1.class.getName() );
+ DialectFactory.registerDialectResolver( TestingDialects.ErrorDialectResolver2.class.getName() );
+ DialectFactory.registerDialectResolver( TestingDialects.MyOverridingDialectResolver1.class.getName() );
+ DialectFactory.registerDialectResolver( "org.hibernate.dialect.NoSuchDialectResolver" );
+ DialectFactory.registerDialectResolver( "java.lang.Object" );
+
+
+ testDetermination( "MyDatabase1", TestingDialects.MyDialect1.class );
+ testDetermination( "MyDatabase2", 1, TestingDialects.MyDialect21.class );
+ testDetermination( "MyTrickyDatabase1", TestingDialects.MyDialect1.class );
+
+ // This should be mapped to DB2Dialect by default, but actually it will be
+ // my custom dialect because I have registered MyOverridingDialectResolver1.
+ testDetermination( "DB2/MySpecialPlatform", TestingDialects.MySpecialDB2Dialect.class );
+
+ try {
+ testDetermination( "ErrorDatabase1", Void.TYPE );
+ fail();
+ }
+ catch ( HibernateException e ) {
+// log.info( "Expected SQL error in resolveDialect and ignored", e );
+ }
+
+ try {
+ testDetermination( "ErrorDatabase2", Void.TYPE );
+ fail();
+ }
+ catch ( HibernateException e ) {
+// log.info( "Expected runtime error in resolveDialect", e );
+ }
+ }
+
+ public void testDialectNotFound() {
+ Properties properties = new Properties();
+ try {
+ DialectFactory.buildDialect( properties, Mocks.createConnection( "NoSuchDatabase", 666 ) );
+ fail();
+ }
+ catch ( HibernateException e ) {
+ assertNull( e.getCause() );
+ }
+ }
+
+ private void testDetermination(String databaseName, Class clazz) {
+ testDetermination( databaseName, -9999, clazz );
+ }
+
+ private void testDetermination(String databaseName, int databaseMajorVersion, Class clazz) {
+ Properties properties = new Properties();
+ Connection conn = Mocks.createConnection( databaseName, databaseMajorVersion );
+ assertEquals( clazz, DialectFactory.buildDialect( properties, conn ).getClass() );
+ }
+}
Added: core/trunk/core/src/test/java/org/hibernate/dialect/resolver/DialectResolverTest.java
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/dialect/resolver/DialectResolverTest.java (rev 0)
+++ core/trunk/core/src/test/java/org/hibernate/dialect/resolver/DialectResolverTest.java 2008-10-13 15:29:23 UTC (rev 15343)
@@ -0,0 +1,121 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.SQLException;
+
+import junit.framework.TestSuite;
+import junit.framework.Test;
+import junit.framework.TestCase;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.TestingDialects;
+import org.hibernate.dialect.Mocks;
+import org.hibernate.exception.JDBCConnectionException;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class DialectResolverTest extends TestCase {
+
+ public DialectResolverTest(String name) {
+ super( name );
+ }
+
+ public void testDialects() throws Exception {
+ DialectResolverSet resolvers = new DialectResolverSet();
+
+ resolvers.addResolverAtFirst( new TestingDialects.MyDialectResolver1() );
+ resolvers.addResolverAtFirst( new TestingDialects.MyDialectResolver2() );
+
+ testDetermination( resolvers, "MyDatabase1", 1, TestingDialects.MyDialect1.class );
+ testDetermination( resolvers, "MyDatabase1", 2, TestingDialects.MyDialect1.class );
+ testDetermination( resolvers, "MyDatabase2", 0, null );
+ testDetermination( resolvers, "MyDatabase2", 1, TestingDialects.MyDialect21.class );
+ testDetermination( resolvers, "MyDatabase2", 2, TestingDialects.MyDialect22.class );
+ testDetermination( resolvers, "MyDatabase2", 3, TestingDialects.MyDialect22.class );
+ testDetermination( resolvers, "MyDatabase3", 1, null );
+ testDetermination( resolvers, "MyTrickyDatabase1", 1, TestingDialects.MyDialect1.class );
+ }
+
+ public void testErrorAndOrder() throws Exception {
+ DialectResolverSet resolvers = new DialectResolverSet();
+ resolvers.addResolverAtFirst( new TestingDialects.MyDialectResolver1() );
+ resolvers.addResolver( new TestingDialects.ErrorDialectResolver1() );
+ resolvers.addResolverAtFirst( new TestingDialects.ErrorDialectResolver1() );
+ resolvers.addResolver( new TestingDialects.MyDialectResolver2() );
+
+ // Non-connection errors are suppressed.
+ testDetermination( resolvers, "MyDatabase1", 1, TestingDialects.MyDialect1.class );
+ testDetermination( resolvers, "MyTrickyDatabase1", 1, TestingDialects.MyDialect1.class );
+ testDetermination( resolvers, "NoSuchDatabase", 1, null );
+
+ // Connection errors are reported
+ try {
+ testDetermination( resolvers, "ConnectionErrorDatabase1", 1, null );
+ fail();
+ }
+ catch ( JDBCConnectionException e ) {
+ // expected
+ }
+ }
+
+ public void testBasicDialectResolver() throws Exception {
+ DialectResolverSet resolvers = new DialectResolverSet();
+ // Simulating MyDialectResolver1 by BasicDialectResolvers
+ resolvers.addResolver( new BasicDialectResolver( "MyDatabase1", TestingDialects.MyDialect1.class ) );
+ resolvers.addResolver( new BasicDialectResolver( "MyDatabase2", 1, TestingDialects.MyDialect21.class ) );
+ resolvers.addResolver( new BasicDialectResolver( "MyDatabase2", 2, TestingDialects.MyDialect22.class ) );
+ resolvers.addResolver( new BasicDialectResolver( "ErrorDatabase1", Object.class ) );
+ testDetermination( resolvers, "MyDatabase1", 1, TestingDialects.MyDialect1.class );
+
+ testDetermination( resolvers, "MyDatabase1", 2, TestingDialects.MyDialect1.class );
+ testDetermination( resolvers, "MyDatabase2", 0, null );
+ testDetermination( resolvers, "MyDatabase2", 1, TestingDialects.MyDialect21.class );
+ testDetermination( resolvers, "MyDatabase2", 2, TestingDialects.MyDialect22.class );
+ testDetermination( resolvers, "ErrorDatabase1", 0, null );
+ }
+
+
+ private void testDetermination(
+ DialectResolver resolver,
+ String databaseName,
+ int version,
+ Class dialectClass) throws SQLException {
+ Dialect dialect = resolver.resolveDialect( Mocks.createConnection( databaseName, version ).getMetaData() );
+ if ( dialectClass == null ) {
+ assertEquals( null, dialect );
+ }
+ else {
+ assertEquals( dialectClass, dialect.getClass() );
+ }
+ }
+
+ public static Test suite() {
+ return new TestSuite( DialectResolverTest.class );
+ }
+}
Added: core/trunk/core/src/test/resources/log4j.properties
===================================================================
--- core/trunk/core/src/test/resources/log4j.properties (rev 0)
+++ core/trunk/core/src/test/resources/log4j.properties 2008-10-13 15:29:23 UTC (rev 15343)
@@ -0,0 +1,33 @@
+#
+# Hibernate, Relational Persistence for Idiomatic Java
+#
+# Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+# indicated by the @author tags or express copyright attribution
+# statements applied by the authors. All third-party contributions are
+# distributed under license by Red Hat Middleware LLC.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# Lesser General Public License, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+# for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this distribution; if not, write to:
+# Free Software Foundation, Inc.
+# 51 Franklin Street, Fifth Floor
+# Boston, MA 02110-1301 USA
+#
+#
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+
+log4j.rootLogger=info, stdout
+
+log4j.logger.org.hibernate.test=info
+log4j.logger.org.hibernate.tool.hbm2ddl=debug
15 years, 7 months
Hibernate SVN: r15342 - in core/branches/Branch_3_3/core/src: main/java/org/hibernate/dialect and 6 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-13 11:16:21 -0400 (Mon, 13 Oct 2008)
New Revision: 15342
Added:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/AbstractDialectResolver.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicDialectResolver.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicSQLExceptionConverter.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolver.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolverSet.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/StandardDialectResolver.java
core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/
core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/Mocks.java
core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/TestingDialects.java
core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/
core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java
core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectResolverTest.java
core/branches/Branch_3_3/core/src/test/resources/
core/branches/Branch_3_3/core/src/test/resources/log4j.properties
Removed:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DialectFactory.java
Modified:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/Environment.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
Log:
HHH-2293 : DialectResolver
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/Environment.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/Environment.java 2008-10-13 15:08:15 UTC (rev 15341)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/Environment.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -240,7 +240,14 @@
* Hibernate SQL {@link org.hibernate.dialect.Dialect} class
*/
public static final String DIALECT ="hibernate.dialect";
+
/**
+ * {@link org.hibernate.dialect.resolver.DialectResolver} classes to register with the
+ * {@link org.hibernate.dialect.resolver.DialectFactory}
+ */
+ public static final String DIALECT_RESOLVERS = "hibernate.dialect_resolvers";
+
+ /**
* A default database schema (owner) name to use for unqualified tablenames
*/
public static final String DEFAULT_SCHEMA = "hibernate.default_schema";
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/SettingsFactory.java 2008-10-13 15:08:15 UTC (rev 15341)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/SettingsFactory.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -25,7 +25,6 @@
package org.hibernate.cfg;
import java.io.Serializable;
-import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
@@ -47,7 +46,7 @@
import org.hibernate.connection.ConnectionProvider;
import org.hibernate.connection.ConnectionProviderFactory;
import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.DialectFactory;
+import org.hibernate.dialect.resolver.DialectFactory;
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.exception.SQLExceptionConverterFactory;
import org.hibernate.hql.QueryTranslatorFactory;
@@ -64,23 +63,24 @@
import org.hibernate.util.StringHelper;
/**
- * Reads configuration properties and configures a <tt>Settings</tt> instance.
+ * Reads configuration properties and builds a {@link Settings} instance.
*
* @author Gavin King
*/
public class SettingsFactory implements Serializable {
+ private static final Logger log = LoggerFactory.getLogger( SettingsFactory.class );
+ private static final long serialVersionUID = -1194386144994524825L;
public static final String DEF_CACHE_REG_FACTORY = NoCachingRegionFactory.class.getName();
- private static final Logger log = LoggerFactory.getLogger(SettingsFactory.class);
protected SettingsFactory() {
}
-
+
public Settings buildSettings(Properties props) {
Settings settings = new Settings();
-
+
//SessionFactory name:
-
+
String sessionFactoryName = props.getProperty(Environment.SESSION_FACTORY_NAME);
settings.setSessionFactoryName(sessionFactoryName);
@@ -91,17 +91,17 @@
//Interrogate JDBC metadata
- String databaseName = null;
- int databaseMajorVersion = 0;
boolean metaSupportsScrollable = false;
boolean metaSupportsGetGeneratedKeys = false;
boolean metaSupportsBatchUpdates = false;
boolean metaReportsDDLCausesTxnCommit = false;
boolean metaReportsDDLInTxnSupported = true;
+ Dialect dialect = null;
// 'hibernate.temp.use_jdbc_metadata_defaults' is a temporary magic value.
- // The need for it is intended to be alleviated with 3.3 developement, thus it is
+ // The need for it is intended to be alleviated with future developement, thus it is
// not defined as an Environment constant...
+ //
// it is used to control whether we should consult the JDBC metadata to determine
// certain Settings default values; it is useful to *not* do this when the database
// may not be available (mainly in tools usage).
@@ -111,46 +111,48 @@
Connection conn = connections.getConnection();
try {
DatabaseMetaData meta = conn.getMetaData();
- databaseName = meta.getDatabaseProductName();
- databaseMajorVersion = getDatabaseMajorVersion(meta);
- log.info("RDBMS: " + databaseName + ", version: " + meta.getDatabaseProductVersion() );
- log.info("JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion() );
+ log.info( "RDBMS: " + meta.getDatabaseProductName() + ", version: " + meta.getDatabaseProductVersion() );
+ log.info( "JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion() );
- metaSupportsScrollable = meta.supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE);
+ dialect = DialectFactory.buildDialect( props, conn );
+
+ metaSupportsScrollable = meta.supportsResultSetType( ResultSet.TYPE_SCROLL_INSENSITIVE );
metaSupportsBatchUpdates = meta.supportsBatchUpdates();
metaReportsDDLCausesTxnCommit = meta.dataDefinitionCausesTransactionCommit();
metaReportsDDLInTxnSupported = !meta.dataDefinitionIgnoredInTransactions();
- metaSupportsGetGeneratedKeys = meta.supportsGetGeneratedKeys();
+ metaSupportsGetGeneratedKeys = meta.supportsGetGeneratedKeys();
}
- catch (SQLException sqle) {
- log.warn("Could not obtain connection metadata", sqle);
+ catch ( SQLException sqle ) {
+ log.warn( "Could not obtain connection metadata", sqle );
}
finally {
- connections.closeConnection(conn);
+ connections.closeConnection( conn );
}
}
- catch (SQLException sqle) {
- log.warn("Could not obtain connection to query metadata", sqle);
+ catch ( SQLException sqle ) {
+ log.warn( "Could not obtain connection to query metadata", sqle );
+ dialect = DialectFactory.buildDialect( props );
}
- catch (UnsupportedOperationException uoe) {
+ catch ( UnsupportedOperationException uoe ) {
// user supplied JDBC connections
+ dialect = DialectFactory.buildDialect( props );
}
}
+ else {
+ dialect = DialectFactory.buildDialect( props );
+ }
+
settings.setDataDefinitionImplicitCommit( metaReportsDDLCausesTxnCommit );
settings.setDataDefinitionInTransactionSupported( metaReportsDDLInTxnSupported );
+ settings.setDialect( dialect );
-
- //SQL Dialect:
- Dialect dialect = determineDialect( props, databaseName, databaseMajorVersion );
- settings.setDialect(dialect);
-
//use dialect default properties
final Properties properties = new Properties();
properties.putAll( dialect.getDefaultProperties() );
- properties.putAll(props);
-
+ properties.putAll( props );
+
// Transaction settings:
-
+
TransactionFactory transactionFactory = createTransactionFactory(properties);
settings.setTransactionFactory(transactionFactory);
settings.setTransactionManagerLookup( createTransactionManagerLookup(properties) );
@@ -173,7 +175,7 @@
if (batchSize>0) log.info("JDBC batch updates for versioned data: " + enabledDisabled(jdbcBatchVersionedData) );
settings.setJdbcBatchVersionedData(jdbcBatchVersionedData);
settings.setBatcherFactory( createBatcherFactory(properties, batchSize) );
-
+
boolean useScrollableResultSets = PropertiesHelper.getBoolean(Environment.USE_SCROLLABLE_RESULTSET, properties, metaSupportsScrollable);
log.info("Scrollable result sets: " + enabledDisabled(useScrollableResultSets) );
settings.setScrollableResultSetsEnabled(useScrollableResultSets);
@@ -224,7 +226,7 @@
boolean comments = PropertiesHelper.getBoolean(Environment.USE_SQL_COMMENTS, properties);
log.info( "Generate SQL with comments: " + enabledDisabled(comments) );
settings.setCommentsEnabled(comments);
-
+
boolean orderUpdates = PropertiesHelper.getBoolean(Environment.ORDER_UPDATES, properties);
log.info( "Order SQL updates by primary key: " + enabledDisabled(orderUpdates) );
settings.setOrderUpdatesEnabled(orderUpdates);
@@ -232,9 +234,9 @@
boolean orderInserts = PropertiesHelper.getBoolean(Environment.ORDER_INSERTS, properties);
log.info( "Order SQL inserts for batching: " + enabledDisabled( orderInserts ) );
settings.setOrderInsertsEnabled( orderInserts );
-
+
//Query parser settings:
-
+
settings.setQueryTranslatorFactory( createQueryTranslatorFactory(properties) );
Map querySubstitutions = PropertiesHelper.toMap(Environment.QUERY_SUBSTITUTIONS, " ,=;:\n\t\r\f", properties);
@@ -244,7 +246,7 @@
boolean jpaqlCompliance = PropertiesHelper.getBoolean( Environment.JPAQL_STRICT_COMPLIANCE, properties, false );
settings.setStrictJPAQLCompliance( jpaqlCompliance );
log.info( "JPA-QL strict compliance: " + enabledDisabled( jpaqlCompliance ) );
-
+
// Second-level / query cache:
boolean useSecondLevelCache = PropertiesHelper.getBoolean(Environment.USE_SECOND_LEVEL_CACHE, properties, true);
@@ -275,9 +277,9 @@
settings.setStructuredCacheEntriesEnabled(useStructuredCacheEntries);
if (useQueryCache) settings.setQueryCacheFactory( createQueryCacheFactory(properties) );
-
+
//SQL Exception converter:
-
+
SQLExceptionConverter sqlExceptionConverter;
try {
sqlExceptionConverter = SQLExceptionConverterFactory.buildSQLExceptionConverter( dialect, properties );
@@ -302,13 +304,13 @@
boolean useStatistics = PropertiesHelper.getBoolean(Environment.GENERATE_STATISTICS, properties);
log.info( "Statistics: " + enabledDisabled(useStatistics) );
settings.setStatisticsEnabled(useStatistics);
-
+
boolean useIdentifierRollback = PropertiesHelper.getBoolean(Environment.USE_IDENTIFIER_ROLLBACK, properties);
log.info( "Deleted entity synthetic identifier rollback: " + enabledDisabled(useIdentifierRollback) );
settings.setIdentifierRollbackEnabled(useIdentifierRollback);
-
+
//Schema export:
-
+
String autoSchemaExport = properties.getProperty(Environment.HBM2DDL_AUTO);
if ( "validate".equals(autoSchemaExport) ) settings.setAutoValidateSchema(true);
if ( "update".equals(autoSchemaExport) ) settings.setAutoUpdateSchema(true);
@@ -348,24 +350,10 @@
}
}
- private int getDatabaseMajorVersion(DatabaseMetaData meta) {
- try {
- Method gdbmvMethod = DatabaseMetaData.class.getMethod("getDatabaseMajorVersion", null);
- return ( (Integer) gdbmvMethod.invoke(meta, null) ).intValue();
- }
- catch (NoSuchMethodException nsme) {
- return 0;
- }
- catch (Throwable t) {
- log.debug("could not get database version from JDBC metadata");
- return 0;
- }
- }
-
private static String enabledDisabled(boolean value) {
return value ? "enabled" : "disabled";
}
-
+
protected QueryCacheFactory createQueryCacheFactory(Properties properties) {
String queryCacheFactoryClassName = PropertiesHelper.getString(
Environment.QUERY_CACHE_FACTORY, properties, "org.hibernate.cache.StandardQueryCacheFactory"
@@ -401,7 +389,7 @@
throw new HibernateException( "could not instantiate RegionFactory [" + regionFactoryClassName + "]", e );
}
}
-
+
protected QueryTranslatorFactory createQueryTranslatorFactory(Properties properties) {
String className = PropertiesHelper.getString(
Environment.QUERY_TRANSLATOR, properties, "org.hibernate.hql.ast.ASTQueryTranslatorFactory"
@@ -414,7 +402,7 @@
throw new HibernateException("could not instantiate QueryTranslatorFactory: " + className, cnfe);
}
}
-
+
protected BatcherFactory createBatcherFactory(Properties properties, int batchSize) {
String batcherClass = properties.getProperty(Environment.BATCH_STRATEGY);
if (batcherClass==null) {
@@ -432,21 +420,17 @@
}
}
}
-
+
protected ConnectionProvider createConnectionProvider(Properties properties) {
return ConnectionProviderFactory.newConnectionProvider(properties);
}
-
+
protected TransactionFactory createTransactionFactory(Properties properties) {
return TransactionFactoryFactory.buildTransactionFactory(properties);
}
-
+
protected TransactionManagerLookup createTransactionManagerLookup(Properties properties) {
- return TransactionManagerLookupFactory.getTransactionManagerLookup(properties);
+ return TransactionManagerLookupFactory.getTransactionManagerLookup(properties);
}
- private Dialect determineDialect(Properties props, String databaseName, int databaseMajorVersion) {
- return DialectFactory.buildDialect( props, databaseName, databaseMajorVersion );
- }
-
}
Deleted: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DialectFactory.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DialectFactory.java 2008-10-13 15:08:15 UTC (rev 15341)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DialectFactory.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -1,179 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- *
- */
-package org.hibernate.dialect;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * A factory for generating Dialect instances.
- *
- * @author Steve Ebersole
- */
-public class DialectFactory {
-
- /**
- * Builds an appropriate Dialect instance.
- * <p/>
- * If a dialect is explicitly named in the incoming properties, it is used. Otherwise, the database name and version
- * (obtained from connection metadata) are used to make the dertemination.
- * <p/>
- * An exception is thrown if a dialect was not explicitly set and the database name is not known.
- *
- * @param props The configuration properties.
- * @param databaseName The name of the database product (obtained from metadata).
- * @param databaseMajorVersion The major version of the database product (obtained from metadata).
- *
- * @return The appropriate dialect.
- *
- * @throws HibernateException No dialect specified and database name not known.
- */
- public static Dialect buildDialect(Properties props, String databaseName, int databaseMajorVersion)
- throws HibernateException {
- String dialectName = props.getProperty( Environment.DIALECT );
- if ( dialectName == null ) {
- return determineDialect( databaseName, databaseMajorVersion );
- }
- else {
- return buildDialect( dialectName );
- }
- }
-
- /**
- * Determine the appropriate Dialect to use given the database product name
- * and major version.
- *
- * @param databaseName The name of the database product (obtained from metadata).
- * @param databaseMajorVersion The major version of the database product (obtained from metadata).
- *
- * @return An appropriate dialect instance.
- */
- public static Dialect determineDialect(String databaseName, int databaseMajorVersion) {
- if ( databaseName == null ) {
- throw new HibernateException( "Hibernate Dialect must be explicitly set" );
- }
-
- DatabaseDialectMapper mapper = ( DatabaseDialectMapper ) MAPPERS.get( databaseName );
- if ( mapper == null ) {
- throw new HibernateException( "Hibernate Dialect must be explicitly set for database: " + databaseName );
- }
-
- String dialectName = mapper.getDialectClass( databaseMajorVersion );
- return buildDialect( dialectName );
- }
-
- /**
- * Returns a dialect instance given the name of the class to use.
- *
- * @param dialectName The name of the dialect class.
- *
- * @return The dialect instance.
- */
- public static Dialect buildDialect(String dialectName) {
- try {
- return ( Dialect ) ReflectHelper.classForName( dialectName ).newInstance();
- }
- catch ( ClassNotFoundException cnfe ) {
- throw new HibernateException( "Dialect class not found: " + dialectName );
- }
- catch ( Exception e ) {
- throw new HibernateException( "Could not instantiate dialect class", e );
- }
- }
-
- /**
- * For a given database product name, instances of
- * DatabaseDialectMapper know which Dialect to use for different versions.
- */
- public static interface DatabaseDialectMapper {
- public String getDialectClass(int majorVersion);
- }
-
- /**
- * A simple DatabaseDialectMapper for dialects which are independent
- * of the underlying database product version.
- */
- public static class VersionInsensitiveMapper implements DatabaseDialectMapper {
- private String dialectClassName;
-
- public VersionInsensitiveMapper(String dialectClassName) {
- this.dialectClassName = dialectClassName;
- }
-
- public String getDialectClass(int majorVersion) {
- return dialectClassName;
- }
- }
-
- // TODO : this is the stuff it'd be nice to move to a properties file or some other easily user-editable place
- private static final Map MAPPERS = new HashMap();
- static {
- // detectors...
- MAPPERS.put( "HSQL Database Engine", new VersionInsensitiveMapper( "org.hibernate.dialect.HSQLDialect" ) );
- MAPPERS.put( "H2", new VersionInsensitiveMapper( "org.hibernate.dialect.H2Dialect" ) );
- MAPPERS.put( "MySQL", new VersionInsensitiveMapper( "org.hibernate.dialect.MySQLDialect" ) );
- MAPPERS.put( "PostgreSQL", new VersionInsensitiveMapper( "org.hibernate.dialect.PostgreSQLDialect" ) );
- MAPPERS.put( "Apache Derby", new VersionInsensitiveMapper( "org.hibernate.dialect.DerbyDialect" ) );
-
- MAPPERS.put( "Ingres", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
- MAPPERS.put( "ingres", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
- MAPPERS.put( "INGRES", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
-
- MAPPERS.put( "Microsoft SQL Server Database", new VersionInsensitiveMapper( "org.hibernate.dialect.SQLServerDialect" ) );
- MAPPERS.put( "Microsoft SQL Server", new VersionInsensitiveMapper( "org.hibernate.dialect.SQLServerDialect" ) );
- MAPPERS.put( "Sybase SQL Server", new VersionInsensitiveMapper( "org.hibernate.dialect.SybaseDialect" ) );
- MAPPERS.put( "Adaptive Server Enterprise", new VersionInsensitiveMapper( "org.hibernate.dialect.SybaseDialect" ) );
-
- MAPPERS.put( "Informix Dynamic Server", new VersionInsensitiveMapper( "org.hibernate.dialect.InformixDialect" ) );
-
- // thanks goodness for "universal" databases...
- MAPPERS.put( "DB2/NT", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
- MAPPERS.put( "DB2/LINUX", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
- MAPPERS.put( "DB2/6000", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
- MAPPERS.put( "DB2/HPUX", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
- MAPPERS.put( "DB2/SUN", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
- MAPPERS.put( "DB2/LINUX390", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
- MAPPERS.put( "DB2/AIX64", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
-
- MAPPERS.put(
- "Oracle",
- new DatabaseDialectMapper() {
- public String getDialectClass(int majorVersion) {
- switch ( majorVersion ) {
- case 8: return Oracle8iDialect.class.getName();
- case 9: return Oracle9iDialect.class.getName();
- case 10: return Oracle10gDialect.class.getName();
- default: throw new HibernateException( "unknown Oracle major version [" + majorVersion + "]" );
- }
- }
- }
- );
- }
-}
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/AbstractDialectResolver.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/AbstractDialectResolver.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/AbstractDialectResolver.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -0,0 +1,80 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.exception.JDBCConnectionException;
+import org.hibernate.JDBCException;
+
+/**
+ * A templated resolver impl which delegates to the {@link #resolveDialectInternal} method
+ * and handles any thrown {@link SQLException}s.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractDialectResolver implements DialectResolver {
+ private static final Logger log = LoggerFactory.getLogger( AbstractDialectResolver.class );
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Here we template the resolution, delegating to {@link #resolveDialectInternal} and handling
+ * {@link java.sql.SQLException}s properly.
+ */
+ public final Dialect resolveDialect(DatabaseMetaData metaData) {
+ try {
+ return resolveDialectInternal( metaData );
+ }
+ catch ( SQLException sqlException ) {
+ JDBCException jdbcException = BasicSQLExceptionConverter.INSTANCE.convert( sqlException );
+ if ( jdbcException instanceof JDBCConnectionException ) {
+ throw jdbcException;
+ }
+ else {
+ log.warn( BasicSQLExceptionConverter.MSG + " : " + sqlException.getMessage() );
+ return null;
+ }
+ }
+ catch ( Throwable t ) {
+ log.warn( "Error executing resolver [" + this + "] : " + t.getMessage() );
+ return null;
+ }
+ }
+
+ /**
+ * Perform the actual resolution without caring about handling {@link SQLException}s.
+ *
+ * @param metaData The database metadata
+ * @return The resolved dialect, or null if we could not resolve.
+ * @throws SQLException Indicates problems accessing the metadata.
+ */
+ protected abstract Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException;
+}
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicDialectResolver.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicDialectResolver.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicDialectResolver.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -0,0 +1,78 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.HibernateException;
+
+/**
+ * Intended as support for custom resolvers.
+ *
+ * @author Steve Ebersole
+ */
+public class BasicDialectResolver extends AbstractDialectResolver {
+ public static final int VERSION_INSENSITIVE_VERSION = -9999;
+
+ private final String matchingName;
+ private final int matchingVersion;
+ private final Class dialectClass;
+
+ public BasicDialectResolver(String matchingName, Class dialectClass) {
+ this( matchingName, VERSION_INSENSITIVE_VERSION, dialectClass );
+ }
+
+ public BasicDialectResolver(String matchingName, int matchingVersion, Class dialectClass) {
+ this.matchingName = matchingName;
+ this.matchingVersion = matchingVersion;
+ this.dialectClass = dialectClass;
+ }
+
+ protected final Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
+ final String databaseName = metaData.getDatabaseProductName();
+ final int databaseMajorVersion = metaData.getDatabaseMajorVersion();
+
+ if ( matchingName.equalsIgnoreCase( databaseName )
+ && ( matchingVersion == VERSION_INSENSITIVE_VERSION || matchingVersion == databaseMajorVersion ) ) {
+ try {
+ return ( Dialect ) dialectClass.newInstance();
+ }
+ catch ( HibernateException e ) {
+ // conceivable that the dialect ctor could throw HibernateExceptions, so don't re-wrap
+ throw e;
+ }
+ catch ( Throwable t ) {
+ throw new HibernateException(
+ "Could not instantiate specified Dialect class [" + dialectClass.getName() + "]",
+ t
+ );
+ }
+ }
+
+ return null;
+ }
+}
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicSQLExceptionConverter.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicSQLExceptionConverter.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicSQLExceptionConverter.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -0,0 +1,62 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.SQLException;
+
+import org.hibernate.exception.SQLStateConverter;
+import org.hibernate.exception.ViolatedConstraintNameExtracter;
+import org.hibernate.JDBCException;
+
+/**
+ * A helper to centralize conversion of {@link java.sql.SQLException}s to {@link org.hibernate.JDBCException}s.
+ *
+ * @author Steve Ebersole
+ */
+public class BasicSQLExceptionConverter {
+ public static final BasicSQLExceptionConverter INSTANCE = new BasicSQLExceptionConverter();
+ public static final String MSG = "Unable to query java.sql.DatabaseMetaData";
+
+ private static final SQLStateConverter CONVERTER = new SQLStateConverter( new ConstraintNameExtracter() );
+
+ /**
+ * Perform a conversion.
+ *
+ * @param sqlException The exception to convert.
+ * @return The converted exception.
+ */
+ public JDBCException convert(SQLException sqlException) {
+ return CONVERTER.convert( sqlException, MSG, null );
+ }
+
+ private static class ConstraintNameExtracter implements ViolatedConstraintNameExtracter {
+ /**
+ * {@inheritDoc}
+ */
+ public String extractConstraintName(SQLException sqle) {
+ return "???";
+ }
+ }
+}
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -0,0 +1,166 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.DatabaseMetaData;
+import java.util.Properties;
+
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.resolver.DialectResolver;
+import org.hibernate.dialect.resolver.DialectResolverSet;
+import org.hibernate.dialect.resolver.StandardDialectResolver;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.cfg.Environment;
+import org.hibernate.util.ReflectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A factory for generating Dialect instances.
+ *
+ * @author Steve Ebersole
+ * @author Tomoto Shimizu Washio
+ */
+public class DialectFactory {
+ private static final Logger log = LoggerFactory.getLogger( DialectFactory.class );
+
+ private static DialectResolverSet DIALECT_RESOLVERS = new DialectResolverSet();
+
+ static {
+ // register the standard dialect resolver
+ DIALECT_RESOLVERS.addResolver( new StandardDialectResolver() );
+
+ // register resolvers set via Environment property
+ String userSpecifedResolverSetting = Environment.getProperties().getProperty( Environment.DIALECT_RESOLVERS );
+ if ( userSpecifedResolverSetting != null ) {
+ String[] userSpecifedResolvers = userSpecifedResolverSetting.split( "\\s+" );
+ for ( int i = 0; i < userSpecifedResolvers.length; i++ ) {
+ registerDialectResolver( userSpecifedResolvers[i] );
+ }
+ }
+ }
+
+ /*package*/ static void registerDialectResolver(String resolverName) {
+ try {
+ DialectResolver resolver = ( DialectResolver ) ReflectHelper.classForName( resolverName ).newInstance();
+ DIALECT_RESOLVERS.addResolverAtFirst( resolver );
+ }
+ catch ( ClassNotFoundException cnfe ) {
+ log.warn( "Dialect resolver class not found: " + resolverName );
+ }
+ catch ( Exception e ) {
+ log.warn( "Could not instantiate dialect resolver class", e );
+ }
+ }
+
+ /**
+ * Builds an appropriate Dialect instance.
+ * <p/>
+ * If a dialect is explicitly named in the incoming properties, it is used. Otherwise, it is
+ * determined by dialect resolvers based on the passed connection.
+ * <p/>
+ * An exception is thrown if a dialect was not explicitly set and no resolver could make
+ * the determination from the given connection.
+ *
+ * @param properties The configuration properties.
+ * @param connection The configured connection.
+ * @return The appropriate dialect instance.
+ * @throws HibernateException No dialect specified and no resolver could make the determination.
+ */
+ public static Dialect buildDialect(Properties properties, Connection connection) throws HibernateException {
+ String dialectName = properties.getProperty( Environment.DIALECT );
+ if ( dialectName == null ) {
+ return determineDialect( connection );
+ }
+ else {
+ return constructDialect( dialectName );
+ }
+ }
+
+ public static Dialect buildDialect(Properties properties) {
+ String dialectName = properties.getProperty( Environment.DIALECT );
+ if ( dialectName == null ) {
+ throw new HibernateException( "'hibernate.dialect' must be set when no Connection avalable" );
+ }
+ return constructDialect( dialectName );
+ }
+
+ /**
+ * Determine the appropriate Dialect to use given the connection.
+ *
+ * @param connection The configured connection.
+ * @return The appropriate dialect instance.
+ *
+ * @throws HibernateException No connection given or no resolver could make
+ * the determination from the given connection.
+ */
+ private static Dialect determineDialect(Connection connection) {
+ if ( connection == null ) {
+ throw new HibernateException( "Connection cannot be null when 'hibernate.dialect' not set" );
+ }
+
+ try {
+ final DatabaseMetaData databaseMetaData = connection.getMetaData();
+ final Dialect dialect = DIALECT_RESOLVERS.resolveDialect( databaseMetaData );
+
+ if ( dialect == null ) {
+ throw new HibernateException(
+ "Unable to determine Dialect to use [name=" + databaseMetaData.getDatabaseProductName() +
+ ", majorVersion=" + databaseMetaData.getDatabaseMajorVersion() +
+ "]; user must register resolver or explicitly set 'hibernate.dialect'"
+ );
+ }
+
+ return dialect;
+ }
+ catch ( SQLException sqlException ) {
+ throw new HibernateException(
+ "Unable to access java.sql.DatabaseMetaData to determine appropriate Dialect to use",
+ sqlException
+ );
+ }
+ }
+
+ /**
+ * Returns a dialect instance given the name of the class to use.
+ *
+ * @param dialectName The name of the dialect class.
+ *
+ * @return The dialect instance.
+ */
+ public static Dialect constructDialect(String dialectName) {
+ try {
+ return ( Dialect ) ReflectHelper.classForName( dialectName ).newInstance();
+ }
+ catch ( ClassNotFoundException cnfe ) {
+ throw new HibernateException( "Dialect class not found: " + dialectName, cnfe );
+ }
+ catch ( Exception e ) {
+ throw new HibernateException( "Could not instantiate dialect class", e );
+ }
+ }
+}
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolver.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolver.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolver.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -0,0 +1,51 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.exception.JDBCConnectionException;
+
+/**
+ * Contract for determining the {@link Dialect} to use based on a JDBC {@link Connection}.
+ *
+ * @author Tomoto Shimizu Washio
+ * @author Steve Ebersole
+ */
+public interface DialectResolver {
+ /**
+ * Determine the {@link Dialect} to use based on the given JDBC {@link DatabaseMetaData}. Implementations are
+ * expected to return the {@link Dialect} instance to use, or null if the {@link DatabaseMetaData} does not match
+ * the criteria handled by this impl.
+ *
+ * @param metaData The JDBC metadata.
+ * @return The dialect to use, or null.
+ * @throws JDBCConnectionException Indicates a 'non transient connection problem', which indicates that
+ * we should stop resolution attempts.
+ */
+ public Dialect resolveDialect(DatabaseMetaData metaData) throws JDBCConnectionException;
+}
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolverSet.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolverSet.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolverSet.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -0,0 +1,92 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.DatabaseMetaData;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.exception.JDBCConnectionException;
+
+/**
+ * A {@link DialectResolver} implementation which coordinates resolution by delegating to its
+ * registered sub-resolvers. Sub-resolvers may be registered by calling either {@link #addResolver} or
+ * {@link #addResolverAtFirst}.
+ *
+ * @author Tomoto Shimizu Washio
+ */
+public class DialectResolverSet implements DialectResolver {
+ private static Logger log = LoggerFactory.getLogger( DialectResolverSet.class );
+
+ private List resolvers = new ArrayList();
+
+ /**
+ * {@inheritDoc}
+ */
+ public Dialect resolveDialect(DatabaseMetaData metaData) {
+ Iterator i = resolvers.iterator();
+ while ( i.hasNext() ) {
+ final DialectResolver resolver = ( DialectResolver ) i.next();
+ try {
+ Dialect dialect = resolver.resolveDialect( metaData );
+ if ( dialect != null ) {
+ return dialect;
+ }
+ }
+ catch ( JDBCConnectionException e ) {
+ throw e;
+ }
+ catch ( Throwable t ) {
+ log.info( "sub-resolver threw unexpected exception, continuing to next : " + t.getMessage() );
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Add a resolver at the end of the underlying resolver list. The resolver added by this method is at lower
+ * priority than any other existing resolvers.
+ *
+ * @param resolver The resolver to add.
+ */
+ public void addResolver(DialectResolver resolver) {
+ resolvers.add( resolver );
+ }
+
+ /**
+ * Add a resolver at the beginning of the underlying resolver list. The resolver added by this method is at higher
+ * priority than any other existing resolvers.
+ *
+ * @param resolver The resolver to add.
+ */
+ public void addResolverAtFirst(DialectResolver resolver) {
+ resolvers.add( 0, resolver );
+ }
+}
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/StandardDialectResolver.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/StandardDialectResolver.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/StandardDialectResolver.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -0,0 +1,118 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.HSQLDialect;
+import org.hibernate.dialect.H2Dialect;
+import org.hibernate.dialect.MySQLDialect;
+import org.hibernate.dialect.PostgreSQLDialect;
+import org.hibernate.dialect.DerbyDialect;
+import org.hibernate.dialect.IngresDialect;
+import org.hibernate.dialect.SQLServerDialect;
+import org.hibernate.dialect.SybaseDialect;
+import org.hibernate.dialect.InformixDialect;
+import org.hibernate.dialect.DB2Dialect;
+import org.hibernate.dialect.Oracle10gDialect;
+import org.hibernate.dialect.Oracle9iDialect;
+import org.hibernate.dialect.Oracle8iDialect;
+
+/**
+ * The standard Hibernate resolver.
+ *
+ * @author Steve Ebersole
+ */
+public class StandardDialectResolver extends AbstractDialectResolver{
+ private static final Logger log = LoggerFactory.getLogger( StandardDialectResolver.class );
+
+ protected Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
+ String databaseName = metaData.getDatabaseProductName();
+ int databaseMajorVersion = metaData.getDatabaseMajorVersion();
+
+ if ( "HSQL Database Engine".equals( databaseName ) ) {
+ return new HSQLDialect();
+ }
+
+ if ( "H2".equals( databaseName ) ) {
+ return new H2Dialect();
+ }
+
+ if ( "MySQL".equals( databaseName ) ) {
+ return new MySQLDialect();
+ }
+
+ if ( "PostgreSQL".equals( databaseName ) ) {
+ return new PostgreSQLDialect();
+ }
+
+ if ( "Apache Derby".equals( databaseName ) ) {
+ return new DerbyDialect();
+ }
+
+ if ( "ingres".equalsIgnoreCase( databaseName ) ) {
+ return new IngresDialect();
+ }
+
+ if ( databaseName.startsWith( "Microsoft SQL Server" ) ) {
+ return new SQLServerDialect();
+ }
+
+ if ( "Sybase SQL Server".equals( databaseName ) || "Adaptive Server Enterprise".equals( databaseName ) ) {
+ return new SybaseDialect();
+ }
+
+ if ( "Informix Dynamic Server".equals( databaseName ) ) {
+ return new InformixDialect();
+ }
+
+ if ( databaseName.startsWith( "DB2/" ) ) {
+ return new DB2Dialect();
+ }
+
+ if ( "Oracle".equals( databaseName ) ) {
+ switch ( databaseMajorVersion ) {
+ case 11:
+ log.warn( "Oracle 11g is not yet fully supported; using 10g dialect" );
+ return new Oracle10gDialect();
+ case 10:
+ return new Oracle10gDialect();
+ case 9:
+ return new Oracle9iDialect();
+ case 8:
+ return new Oracle8iDialect();
+ default:
+ log.warn( "unknown Oracle major version [" + databaseMajorVersion + "]" );
+ }
+ }
+
+ return null;
+ }
+}
Added: core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/Mocks.java
===================================================================
--- core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/Mocks.java (rev 0)
+++ core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/Mocks.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -0,0 +1,148 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.SQLException;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class Mocks {
+
+ public static Connection createConnection(String dbName, int version) {
+ DatabaseMetaDataHandler metadataHandler = new DatabaseMetaDataHandler( dbName, version );
+ ConnectionHandler connectionHandler = new ConnectionHandler();
+
+ DatabaseMetaData metadataProxy = ( DatabaseMetaData ) Proxy.newProxyInstance(
+ ClassLoader.getSystemClassLoader(),
+ new Class[] { DatabaseMetaData.class },
+ metadataHandler
+ );
+
+ Connection connectionProxy = ( Connection ) Proxy.newProxyInstance(
+ ClassLoader.getSystemClassLoader(),
+ new Class[] { Connection.class },
+ connectionHandler
+ );
+
+ metadataHandler.setConnectionProxy( connectionProxy );
+ connectionHandler.setMetadataProxy( metadataProxy );
+
+ return connectionProxy;
+ }
+
+ private static class ConnectionHandler implements InvocationHandler {
+ private DatabaseMetaData metadataProxy;
+
+ public void setMetadataProxy(DatabaseMetaData metadataProxy) {
+ this.metadataProxy = metadataProxy;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ final String methodName = method.getName();
+ if ( "getMetaData".equals( methodName ) ) {
+ return metadataProxy;
+ }
+
+ if ( "toString".equals( methodName ) ) {
+ return "Connection proxy [@" + hashCode() + "]";
+ }
+
+ if ( "hashCode".equals( methodName ) ) {
+ return new Integer( this.hashCode() );
+ }
+
+ if ( canThrowSQLException( method ) ) {
+ throw new SQLException();
+ }
+ else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ private static class DatabaseMetaDataHandler implements InvocationHandler {
+ private final String databaseName;
+ private final int majorVersion;
+
+ private Connection connectionProxy;
+
+ public void setConnectionProxy(Connection connectionProxy) {
+ this.connectionProxy = connectionProxy;
+ }
+
+ private DatabaseMetaDataHandler(String databaseName, int majorVersion) {
+ this.databaseName = databaseName;
+ this.majorVersion = majorVersion;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ final String methodName = method.getName();
+ if ( "getDatabaseProductName".equals( methodName ) ) {
+ return databaseName;
+ }
+
+ if ( "getDatabaseMajorVersion".equals( methodName ) ) {
+ return new Integer( majorVersion );
+ }
+
+ if ( "getConnection".equals( methodName ) ) {
+ return connectionProxy;
+ }
+
+ if ( "toString".equals( methodName ) ) {
+ return "DatabaseMetaData proxy [db-name=" + databaseName + ", version=" + majorVersion + "]";
+ }
+
+ if ( "hashCode".equals( methodName ) ) {
+ return new Integer( this.hashCode() );
+ }
+
+ if ( canThrowSQLException( method ) ) {
+ throw new SQLException();
+ }
+ else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ private static boolean canThrowSQLException(Method method) {
+ final Class[] exceptions = method.getExceptionTypes();
+ for ( int i = 0; i < exceptions.length; i++ ) {
+ if ( SQLException.class.isAssignableFrom( exceptions[i] ) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
Added: core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/TestingDialects.java
===================================================================
--- core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/TestingDialects.java (rev 0)
+++ core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/TestingDialects.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -0,0 +1,109 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect;
+
+import java.sql.SQLException;
+import java.sql.DatabaseMetaData;
+
+import org.hibernate.dialect.resolver.AbstractDialectResolver;
+import org.hibernate.dialect.resolver.BasicDialectResolver;
+import org.hibernate.HibernateException;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class TestingDialects {
+
+ public static class MyDialect1 extends Dialect {
+ }
+
+ public static class MyDialect21 extends Dialect {
+ }
+
+ public static class MyDialect22 extends Dialect {
+ }
+
+ public static class MySpecialDB2Dialect extends Dialect {
+ }
+
+ public static class MyDialectResolver1 extends AbstractDialectResolver {
+ protected Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
+ String databaseName = metaData.getDatabaseProductName();
+ int databaseMajorVersion = metaData.getDatabaseMajorVersion();
+ if ( "MyDatabase1".equals( databaseName ) ) {
+ return new MyDialect1();
+ }
+ if ( "MyDatabase2".equals( databaseName ) ) {
+ if ( databaseMajorVersion >= 2 ) {
+ return new MyDialect22();
+ }
+ if ( databaseMajorVersion >= 1 ) {
+ return new MyDialect21();
+ }
+ }
+ return null;
+ }
+ }
+
+ public static class MyDialectResolver2 extends BasicDialectResolver {
+ public MyDialectResolver2() {
+ super( "MyTrickyDatabase1", MyDialect1.class );
+ }
+ }
+
+ public static class ErrorDialectResolver1 extends AbstractDialectResolver {
+ public Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
+ String databaseName = metaData.getDatabaseProductName();
+ if ( databaseName.equals( "ConnectionErrorDatabase1" ) ) {
+ throw new SQLException( "Simulated connection error", "08001" );
+ }
+ else {
+ throw new SQLException();
+ }
+ }
+ }
+
+ public static class ErrorDialectResolver2 extends AbstractDialectResolver {
+ public Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
+ String databaseName = metaData.getDatabaseProductName();
+ if ( databaseName.equals( "ErrorDatabase1" ) ) {
+ throw new SQLException();
+ }
+ if ( databaseName.equals( "ErrorDatabase2" ) ) {
+ throw new HibernateException( "This is a trap!" );
+ }
+ return null;
+ }
+ }
+
+ public static class MyOverridingDialectResolver1 extends BasicDialectResolver {
+ public MyOverridingDialectResolver1() {
+ super( "DB2/MySpecialPlatform", MySpecialDB2Dialect.class );
+ }
+ }
+
+}
Added: core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java
===================================================================
--- core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java (rev 0)
+++ core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -0,0 +1,187 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.util.Properties;
+import java.sql.Connection;
+
+import junit.framework.TestSuite;
+import junit.framework.TestCase;
+import junit.framework.Test;
+
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.resolver.DialectFactory;
+import org.hibernate.dialect.HSQLDialect;
+import org.hibernate.dialect.H2Dialect;
+import org.hibernate.dialect.MySQLDialect;
+import org.hibernate.dialect.PostgreSQLDialect;
+import org.hibernate.dialect.DerbyDialect;
+import org.hibernate.dialect.IngresDialect;
+import org.hibernate.dialect.SQLServerDialect;
+import org.hibernate.dialect.SybaseDialect;
+import org.hibernate.dialect.InformixDialect;
+import org.hibernate.dialect.DB2Dialect;
+import org.hibernate.dialect.Oracle8iDialect;
+import org.hibernate.dialect.Oracle9iDialect;
+import org.hibernate.dialect.Oracle10gDialect;
+import org.hibernate.dialect.TestingDialects;
+import org.hibernate.dialect.Mocks;
+import org.hibernate.cfg.Environment;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class DialectFactoryTest extends TestCase {
+ public DialectFactoryTest(String name) {
+ super( name );
+ }
+
+ public static Test suite() {
+ return new TestSuite( DialectFactoryTest.class );
+ }
+
+ public void testBuildDialectByClass() {
+ assertEquals(
+ HSQLDialect.class,
+ DialectFactory.constructDialect( "org.hibernate.dialect.HSQLDialect" ).getClass()
+ );
+
+ try {
+ DialectFactory.constructDialect( "org.hibernate.dialect.NoSuchDialect" );
+ fail();
+ }
+ catch ( HibernateException e ) {
+ assertEquals( "unexpected exception type", e.getCause().getClass(), ClassNotFoundException.class );
+ }
+
+ try {
+ DialectFactory.constructDialect( "java.lang.Object" );
+ fail();
+ }
+ catch ( HibernateException e ) {
+ assertEquals( "unexpected exception type", e.getCause().getClass(), ClassCastException.class );
+ }
+ }
+
+ public void testBuildDialectByProperties() {
+ Properties props = new Properties();
+
+ try {
+ DialectFactory.buildDialect( props, null );
+ fail();
+ }
+ catch ( HibernateException e ) {
+ assertNull( e.getCause() );
+ }
+
+ props.setProperty( Environment.DIALECT, "org.hibernate.dialect.HSQLDialect" );
+ assertTrue( DialectFactory.buildDialect( props, null ) instanceof HSQLDialect );
+ }
+
+ public void testPreregisteredDialects() {
+ testDetermination( "HSQL Database Engine", HSQLDialect.class );
+ testDetermination( "H2", H2Dialect.class );
+ testDetermination( "MySQL", MySQLDialect.class );
+ testDetermination( "PostgreSQL", PostgreSQLDialect.class );
+ testDetermination( "Apache Derby", DerbyDialect.class );
+ testDetermination( "Ingres", IngresDialect.class );
+ testDetermination( "ingres", IngresDialect.class );
+ testDetermination( "INGRES", IngresDialect.class );
+ testDetermination( "Microsoft SQL Server Database", SQLServerDialect.class );
+ testDetermination( "Microsoft SQL Server", SQLServerDialect.class );
+ testDetermination( "Sybase SQL Server", SybaseDialect.class );
+ testDetermination( "Adaptive Server Enterprise", SybaseDialect.class );
+ testDetermination( "Informix Dynamic Server", InformixDialect.class );
+ testDetermination( "DB2/NT", DB2Dialect.class );
+ testDetermination( "DB2/LINUX", DB2Dialect.class );
+ testDetermination( "DB2/6000", DB2Dialect.class );
+ testDetermination( "DB2/HPUX", DB2Dialect.class );
+ testDetermination( "DB2/SUN", DB2Dialect.class );
+ testDetermination( "DB2/LINUX390", DB2Dialect.class );
+ testDetermination( "DB2/AIX64", DB2Dialect.class );
+ testDetermination( "Oracle", 8, Oracle8iDialect.class );
+ testDetermination( "Oracle", 9, Oracle9iDialect.class );
+ testDetermination( "Oracle", 10, Oracle10gDialect.class );
+ testDetermination( "Oracle", 11, Oracle10gDialect.class );
+ }
+
+ public void testCustomDialects() {
+ DialectFactory.registerDialectResolver( TestingDialects.MyDialectResolver1.class.getName() );
+ DialectFactory.registerDialectResolver( TestingDialects.MyDialectResolver2.class.getName() );
+ DialectFactory.registerDialectResolver( TestingDialects.ErrorDialectResolver1.class.getName() );
+ DialectFactory.registerDialectResolver( TestingDialects.ErrorDialectResolver2.class.getName() );
+ DialectFactory.registerDialectResolver( TestingDialects.MyOverridingDialectResolver1.class.getName() );
+ DialectFactory.registerDialectResolver( "org.hibernate.dialect.NoSuchDialectResolver" );
+ DialectFactory.registerDialectResolver( "java.lang.Object" );
+
+
+ testDetermination( "MyDatabase1", TestingDialects.MyDialect1.class );
+ testDetermination( "MyDatabase2", 1, TestingDialects.MyDialect21.class );
+ testDetermination( "MyTrickyDatabase1", TestingDialects.MyDialect1.class );
+
+ // This should be mapped to DB2Dialect by default, but actually it will be
+ // my custom dialect because I have registered MyOverridingDialectResolver1.
+ testDetermination( "DB2/MySpecialPlatform", TestingDialects.MySpecialDB2Dialect.class );
+
+ try {
+ testDetermination( "ErrorDatabase1", Void.TYPE );
+ fail();
+ }
+ catch ( HibernateException e ) {
+// log.info( "Expected SQL error in resolveDialect and ignored", e );
+ }
+
+ try {
+ testDetermination( "ErrorDatabase2", Void.TYPE );
+ fail();
+ }
+ catch ( HibernateException e ) {
+// log.info( "Expected runtime error in resolveDialect", e );
+ }
+ }
+
+ public void testDialectNotFound() {
+ Properties properties = new Properties();
+ try {
+ DialectFactory.buildDialect( properties, Mocks.createConnection( "NoSuchDatabase", 666 ) );
+ fail();
+ }
+ catch ( HibernateException e ) {
+ assertNull( e.getCause() );
+ }
+ }
+
+ private void testDetermination(String databaseName, Class clazz) {
+ testDetermination( databaseName, -9999, clazz );
+ }
+
+ private void testDetermination(String databaseName, int databaseMajorVersion, Class clazz) {
+ Properties properties = new Properties();
+ Connection conn = Mocks.createConnection( databaseName, databaseMajorVersion );
+ assertEquals( clazz, DialectFactory.buildDialect( properties, conn ).getClass() );
+ }
+}
Added: core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectResolverTest.java
===================================================================
--- core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectResolverTest.java (rev 0)
+++ core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectResolverTest.java 2008-10-13 15:16:21 UTC (rev 15342)
@@ -0,0 +1,121 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.dialect.resolver;
+
+import java.sql.SQLException;
+
+import junit.framework.TestSuite;
+import junit.framework.Test;
+import junit.framework.TestCase;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.TestingDialects;
+import org.hibernate.dialect.Mocks;
+import org.hibernate.exception.JDBCConnectionException;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class DialectResolverTest extends TestCase {
+
+ public DialectResolverTest(String name) {
+ super( name );
+ }
+
+ public void testDialects() throws Exception {
+ DialectResolverSet resolvers = new DialectResolverSet();
+
+ resolvers.addResolverAtFirst( new TestingDialects.MyDialectResolver1() );
+ resolvers.addResolverAtFirst( new TestingDialects.MyDialectResolver2() );
+
+ testDetermination( resolvers, "MyDatabase1", 1, TestingDialects.MyDialect1.class );
+ testDetermination( resolvers, "MyDatabase1", 2, TestingDialects.MyDialect1.class );
+ testDetermination( resolvers, "MyDatabase2", 0, null );
+ testDetermination( resolvers, "MyDatabase2", 1, TestingDialects.MyDialect21.class );
+ testDetermination( resolvers, "MyDatabase2", 2, TestingDialects.MyDialect22.class );
+ testDetermination( resolvers, "MyDatabase2", 3, TestingDialects.MyDialect22.class );
+ testDetermination( resolvers, "MyDatabase3", 1, null );
+ testDetermination( resolvers, "MyTrickyDatabase1", 1, TestingDialects.MyDialect1.class );
+ }
+
+ public void testErrorAndOrder() throws Exception {
+ DialectResolverSet resolvers = new DialectResolverSet();
+ resolvers.addResolverAtFirst( new TestingDialects.MyDialectResolver1() );
+ resolvers.addResolver( new TestingDialects.ErrorDialectResolver1() );
+ resolvers.addResolverAtFirst( new TestingDialects.ErrorDialectResolver1() );
+ resolvers.addResolver( new TestingDialects.MyDialectResolver2() );
+
+ // Non-connection errors are suppressed.
+ testDetermination( resolvers, "MyDatabase1", 1, TestingDialects.MyDialect1.class );
+ testDetermination( resolvers, "MyTrickyDatabase1", 1, TestingDialects.MyDialect1.class );
+ testDetermination( resolvers, "NoSuchDatabase", 1, null );
+
+ // Connection errors are reported
+ try {
+ testDetermination( resolvers, "ConnectionErrorDatabase1", 1, null );
+ fail();
+ }
+ catch ( JDBCConnectionException e ) {
+ // expected
+ }
+ }
+
+ public void testBasicDialectResolver() throws Exception {
+ DialectResolverSet resolvers = new DialectResolverSet();
+ // Simulating MyDialectResolver1 by BasicDialectResolvers
+ resolvers.addResolver( new BasicDialectResolver( "MyDatabase1", TestingDialects.MyDialect1.class ) );
+ resolvers.addResolver( new BasicDialectResolver( "MyDatabase2", 1, TestingDialects.MyDialect21.class ) );
+ resolvers.addResolver( new BasicDialectResolver( "MyDatabase2", 2, TestingDialects.MyDialect22.class ) );
+ resolvers.addResolver( new BasicDialectResolver( "ErrorDatabase1", Object.class ) );
+ testDetermination( resolvers, "MyDatabase1", 1, TestingDialects.MyDialect1.class );
+
+ testDetermination( resolvers, "MyDatabase1", 2, TestingDialects.MyDialect1.class );
+ testDetermination( resolvers, "MyDatabase2", 0, null );
+ testDetermination( resolvers, "MyDatabase2", 1, TestingDialects.MyDialect21.class );
+ testDetermination( resolvers, "MyDatabase2", 2, TestingDialects.MyDialect22.class );
+ testDetermination( resolvers, "ErrorDatabase1", 0, null );
+ }
+
+
+ private void testDetermination(
+ DialectResolver resolver,
+ String databaseName,
+ int version,
+ Class dialectClass) throws SQLException {
+ Dialect dialect = resolver.resolveDialect( Mocks.createConnection( databaseName, version ).getMetaData() );
+ if ( dialectClass == null ) {
+ assertEquals( null, dialect );
+ }
+ else {
+ assertEquals( dialectClass, dialect.getClass() );
+ }
+ }
+
+ public static Test suite() {
+ return new TestSuite( DialectResolverTest.class );
+ }
+}
Added: core/branches/Branch_3_3/core/src/test/resources/log4j.properties
===================================================================
--- core/branches/Branch_3_3/core/src/test/resources/log4j.properties (rev 0)
+++ core/branches/Branch_3_3/core/src/test/resources/log4j.properties 2008-10-13 15:16:21 UTC (rev 15342)
@@ -0,0 +1,33 @@
+#
+# Hibernate, Relational Persistence for Idiomatic Java
+#
+# Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+# indicated by the @author tags or express copyright attribution
+# statements applied by the authors. All third-party contributions are
+# distributed under license by Red Hat Middleware LLC.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# Lesser General Public License, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+# for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this distribution; if not, write to:
+# Free Software Foundation, Inc.
+# 51 Franklin Street, Fifth Floor
+# Boston, MA 02110-1301 USA
+#
+#
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+
+log4j.rootLogger=info, stdout
+
+log4j.logger.org.hibernate.test=info
+log4j.logger.org.hibernate.tool.hbm2ddl=debug
15 years, 7 months
Hibernate SVN: r15341 - in core/trunk/core/src/main/java/org/hibernate: util and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-13 11:08:15 -0400 (Mon, 13 Oct 2008)
New Revision: 15341
Modified:
core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizerFactory.java
core/trunk/core/src/main/java/org/hibernate/util/ReflectHelper.java
Log:
HHH-3517 : default Tuplizer impls
Modified: core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizerFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizerFactory.java 2008-10-13 15:07:52 UTC (rev 15340)
+++ core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizerFactory.java 2008-10-13 15:08:15 UTC (rev 15341)
@@ -140,7 +140,8 @@
}
private boolean hasProperConstructor(Class tuplizerClass) {
- return getProperConstructor( tuplizerClass ) != null;
+ return getProperConstructor( tuplizerClass ) != null
+ && ! ReflectHelper.isAbstractClass( tuplizerClass );
}
private Constructor getProperConstructor(Class clazz) {
Modified: core/trunk/core/src/main/java/org/hibernate/util/ReflectHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/ReflectHelper.java 2008-10-13 15:07:52 UTC (rev 15340)
+++ core/trunk/core/src/main/java/org/hibernate/util/ReflectHelper.java 2008-10-13 15:08:15 UTC (rev 15341)
@@ -144,14 +144,7 @@
*/
public static boolean implementsInterface(Class clazz, Class intf) {
assert intf.isInterface() : "Interface to check was not an interface";
-
- Class[] interfaces = clazz.getInterfaces();
- for ( int i = 0; i < interfaces.length; i++ ) {
- if ( intf.isAssignableFrom( interfaces[i] ) ) {
- return true;
- }
- }
- return false;
+ return intf.isAssignableFrom( clazz );
}
/**
15 years, 7 months
Hibernate SVN: r15340 - in core/branches/Branch_3_2/src/org/hibernate: util and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-13 11:07:52 -0400 (Mon, 13 Oct 2008)
New Revision: 15340
Modified:
core/branches/Branch_3_2/src/org/hibernate/tuple/entity/EntityTuplizerFactory.java
core/branches/Branch_3_2/src/org/hibernate/util/ReflectHelper.java
Log:
HHH-3517 : default Tuplizer impls
Modified: core/branches/Branch_3_2/src/org/hibernate/tuple/entity/EntityTuplizerFactory.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/tuple/entity/EntityTuplizerFactory.java 2008-10-13 15:05:19 UTC (rev 15339)
+++ core/branches/Branch_3_2/src/org/hibernate/tuple/entity/EntityTuplizerFactory.java 2008-10-13 15:07:52 UTC (rev 15340)
@@ -140,7 +140,8 @@
}
private boolean hasProperConstructor(Class tuplizerClass) {
- return getProperConstructor( tuplizerClass ) != null;
+ return getProperConstructor( tuplizerClass ) != null
+ && ! ReflectHelper.isAbstractClass( tuplizerClass );
}
private Constructor getProperConstructor(Class clazz) {
Modified: core/branches/Branch_3_2/src/org/hibernate/util/ReflectHelper.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/util/ReflectHelper.java 2008-10-13 15:05:19 UTC (rev 15339)
+++ core/branches/Branch_3_2/src/org/hibernate/util/ReflectHelper.java 2008-10-13 15:07:52 UTC (rev 15340)
@@ -121,14 +121,7 @@
*/
public static boolean implementsInterface(Class clazz, Class intf) {
assert intf.isInterface() : "Interface to check was not an interface";
-
- Class[] interfaces = clazz.getInterfaces();
- for ( int i = 0; i < interfaces.length; i++ ) {
- if ( intf.isAssignableFrom( interfaces[i] ) ) {
- return true;
- }
- }
- return false;
+ return intf.isAssignableFrom( clazz );
}
/**
15 years, 7 months
Hibernate SVN: r15339 - in core/branches/Branch_3_3/core/src/main/java/org/hibernate: util and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-13 11:05:19 -0400 (Mon, 13 Oct 2008)
New Revision: 15339
Modified:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizerFactory.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/util/ReflectHelper.java
Log:
HHH-3517 : default Tuplizer impls
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizerFactory.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizerFactory.java 2008-10-13 14:13:15 UTC (rev 15338)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizerFactory.java 2008-10-13 15:05:19 UTC (rev 15339)
@@ -140,7 +140,8 @@
}
private boolean hasProperConstructor(Class tuplizerClass) {
- return getProperConstructor( tuplizerClass ) != null;
+ return getProperConstructor( tuplizerClass ) != null
+ && ! ReflectHelper.isAbstractClass( tuplizerClass );
}
private Constructor getProperConstructor(Class clazz) {
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/util/ReflectHelper.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/util/ReflectHelper.java 2008-10-13 14:13:15 UTC (rev 15338)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/util/ReflectHelper.java 2008-10-13 15:05:19 UTC (rev 15339)
@@ -144,14 +144,7 @@
*/
public static boolean implementsInterface(Class clazz, Class intf) {
assert intf.isInterface() : "Interface to check was not an interface";
-
- Class[] interfaces = clazz.getInterfaces();
- for ( int i = 0; i < interfaces.length; i++ ) {
- if ( intf.isAssignableFrom( interfaces[i] ) ) {
- return true;
- }
- }
- return false;
+ return intf.isAssignableFrom( clazz );
}
/**
15 years, 7 months