diff --git a/hibernate-core/src/main/java/org/hibernate/boot/jaxb/mapping/spi/JaxbLockableAttribute.java b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/mapping/spi/JaxbLockableAttribute.java
index 98a2ee6814ce..50619d918364 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/jaxb/mapping/spi/JaxbLockableAttribute.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/mapping/spi/JaxbLockableAttribute.java
@@ -10,6 +10,6 @@
* @author Steve Ebersole
*/
public interface JaxbLockableAttribute extends JaxbPersistentAttribute {
- boolean isOptimisticLock();
+ Boolean isOptimisticLock();
void setOptimisticLock(Boolean value);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/AttributeProcessor.java b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/AttributeProcessor.java
index c579b42a51fe..e3e3ee18fb15 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/AttributeProcessor.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/AttributeProcessor.java
@@ -10,6 +10,7 @@
import org.hibernate.boot.jaxb.mapping.spi.JaxbAssociationOverrideImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributeOverrideImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainer;
+import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainerImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbBaseAttributesContainer;
import org.hibernate.boot.jaxb.mapping.spi.JaxbBasicImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollectionImpl;
@@ -22,6 +23,7 @@
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistentAttribute;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAnyMappingImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbTransientImpl;
+import org.hibernate.boot.jaxb.mapping.spi.JaxbVersionImpl;
import org.hibernate.boot.models.HibernateAnnotations;
import org.hibernate.boot.models.xml.internal.attr.AnyMappingAttributeProcessing;
import org.hibernate.boot.models.xml.internal.attr.BasicAttributeProcessing;
@@ -151,12 +153,21 @@ public interface MemberAdjuster {
}
public static void processAttributes(
- JaxbAttributesContainer attributesContainer,
+ JaxbAttributesContainerImpl attributesContainer,
MutableClassDetails mutableClassDetails,
AccessType classAccessType,
XmlDocumentContext xmlDocumentContext) {
processAttributes( attributesContainer, mutableClassDetails, classAccessType, null, xmlDocumentContext );
}
+ public static void processAttributes(
+ JaxbAttributesContainerImpl attributesContainer,
+ MutableClassDetails mutableClassDetails,
+ AccessType classAccessType,
+ MemberAdjuster memberAdjuster,
+ XmlDocumentContext xmlDocumentContext) {
+ processAttributes( (JaxbAttributesContainer) attributesContainer, mutableClassDetails, classAccessType, memberAdjuster, xmlDocumentContext );
+ processVersionAttribute( attributesContainer.getVersion(), mutableClassDetails, classAccessType, xmlDocumentContext );
+ }
public static void processAttributes(
JaxbAttributesContainer attributesContainer,
@@ -265,4 +276,17 @@ public static void processAssociationOverrides(
xmlDocumentContext
);
}
+
+ public static void processVersionAttribute(
+ JaxbVersionImpl version,
+ MutableClassDetails mutableClassDetails, AccessType classAccessType,
+ XmlDocumentContext xmlDocumentContext
+ ) {
+ XmlAnnotationHelper.applyVersion(
+ version,
+ mutableClassDetails,
+ classAccessType,
+ xmlDocumentContext
+ );
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlAnnotationHelper.java b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlAnnotationHelper.java
index 9a944d0b0b50..36608dcaed68 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlAnnotationHelper.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlAnnotationHelper.java
@@ -24,6 +24,7 @@
import java.util.UUID;
import java.util.function.Consumer;
+import jakarta.persistence.AccessType;
import org.hibernate.AnnotationException;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.NotFoundAction;
@@ -73,6 +74,7 @@
import org.hibernate.boot.jaxb.mapping.spi.JaxbUniqueConstraintImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbUserTypeImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbUuidGeneratorImpl;
+import org.hibernate.boot.jaxb.mapping.spi.JaxbVersionImpl;
import org.hibernate.boot.models.HibernateAnnotations;
import org.hibernate.boot.models.JpaAnnotations;
import org.hibernate.boot.models.XmlAnnotations;
@@ -81,6 +83,7 @@
import org.hibernate.boot.models.annotations.spi.DatabaseObjectDetails;
import org.hibernate.boot.models.JpaEventListenerStyle;
import org.hibernate.boot.models.spi.JpaEventListener;
+import org.hibernate.boot.models.xml.internal.attr.CommonAttributeProcessing;
import org.hibernate.boot.models.xml.internal.db.ForeignKeyProcessing;
import org.hibernate.boot.models.xml.internal.db.JoinColumnProcessing;
import org.hibernate.boot.models.xml.internal.db.TableProcessing;
@@ -136,6 +139,7 @@
import static org.hibernate.boot.models.JpaAnnotations.UNIQUE_CONSTRAINT;
import static org.hibernate.boot.models.xml.internal.UserTypeCasesMapKey.MAP_KEY_USER_TYPE_CASES;
import static org.hibernate.boot.models.xml.internal.UserTypeCasesStandard.STANDARD_USER_TYPE_CASES;
+import static org.hibernate.internal.util.NullnessHelper.coalesce;
import static org.hibernate.internal.util.StringHelper.isEmpty;
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
import static org.hibernate.internal.util.StringHelper.unqualify;
@@ -1701,4 +1705,32 @@ public static void applyCollectionClassification(
);
collectionClassification.value( classification );
}
+
+ public static void applyVersion(JaxbVersionImpl version, MutableClassDetails mutableClassDetails, AccessType classAccessType, XmlDocumentContext xmlDocumentContext) {
+ if ( version != null ) {
+ final AccessType accessType = coalesce( version.getAccess(), classAccessType );
+ final String versionAttributeName = version.getName();
+
+ final MutableMemberDetails memberDetails = XmlProcessingHelper.getAttributeMember(
+ versionAttributeName,
+ accessType,
+ mutableClassDetails
+ );
+ memberDetails.applyAnnotationUsage(
+ JpaAnnotations.VERSION,
+ xmlDocumentContext.getModelBuildingContext()
+ );
+ CommonAttributeProcessing.applyAccess( accessType, memberDetails, xmlDocumentContext );
+ CommonAttributeProcessing.applyAttributeAccessor( version, memberDetails, xmlDocumentContext );
+ XmlAnnotationHelper.applyTemporal( version.getTemporal(), memberDetails, xmlDocumentContext );
+ if ( version.getColumn() != null ) {
+ final ColumnJpaAnnotation columnAnn = (ColumnJpaAnnotation) memberDetails.applyAnnotationUsage(
+ JpaAnnotations.COLUMN,
+ xmlDocumentContext.getModelBuildingContext()
+ );
+ columnAnn.apply( version.getColumn(), xmlDocumentContext );
+ XmlAnnotationHelper.applyColumnTransformation( version.getColumn(), memberDetails, xmlDocumentContext );
+ }
+ }
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/attr/CommonAttributeProcessing.java b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/attr/CommonAttributeProcessing.java
index 47f483f13efa..d672ccec2708 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/attr/CommonAttributeProcessing.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/attr/CommonAttributeProcessing.java
@@ -84,12 +84,15 @@ public static void applyOptimisticLock(
JaxbLockableAttribute jaxbAttribute,
MutableMemberDetails memberDetails,
XmlDocumentContext xmlDocumentContext) {
- final boolean includeInOptimisticLock = jaxbAttribute.isOptimisticLock();
- final OptimisticLockAnnotation optLockAnn = (OptimisticLockAnnotation) memberDetails.applyAnnotationUsage(
- HibernateAnnotations.OPTIMISTIC_LOCK,
- xmlDocumentContext.getModelBuildingContext()
- );
- optLockAnn.excluded( !includeInOptimisticLock );
+ final Boolean includeInOptimisticLock = jaxbAttribute.isOptimisticLock();
+
+ if ( includeInOptimisticLock != null ) {
+ final OptimisticLockAnnotation optLockAnn = (OptimisticLockAnnotation) memberDetails.applyAnnotationUsage(
+ HibernateAnnotations.OPTIMISTIC_LOCK,
+ xmlDocumentContext.getModelBuildingContext()
+ );
+ optLockAnn.excluded( !includeInOptimisticLock );
+ }
}
public static void applyFetching(
diff --git a/hibernate-core/src/main/resources/org/hibernate/xsd/mapping/mapping-7.0.xsd b/hibernate-core/src/main/resources/org/hibernate/xsd/mapping/mapping-7.0.xsd
index 058843f32b66..83f066cccec6 100644
--- a/hibernate-core/src/main/resources/org/hibernate/xsd/mapping/mapping-7.0.xsd
+++ b/hibernate-core/src/main/resources/org/hibernate/xsd/mapping/mapping-7.0.xsd
@@ -601,7 +601,7 @@
-
+
@@ -1027,7 +1027,7 @@
-
+
@@ -1109,7 +1109,7 @@
-
+
@@ -1614,7 +1614,7 @@
-
+
@@ -1661,7 +1661,7 @@
-
+
@@ -2057,7 +2057,7 @@
-
+
@@ -2113,7 +2113,7 @@
-
+
@@ -3139,7 +3139,7 @@
-
+
@@ -3208,7 +3208,7 @@
-
+
@@ -3532,4 +3532,4 @@
-
\ No newline at end of file
+
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/BaseShop.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/BaseShop.java
new file mode 100644
index 000000000000..75cfab1df2f8
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/BaseShop.java
@@ -0,0 +1,30 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright Red Hat Inc. and Hibernate Authors
+ */
+package org.hibernate.orm.test.jpa.xml;
+
+
+
+public class BaseShop {
+
+ private int id;
+
+ private int version;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setVersion(int version) {
+ this.version = version;
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/Consumer.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/Consumer.java
new file mode 100644
index 000000000000..b5e935259811
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/Consumer.java
@@ -0,0 +1,45 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright Red Hat Inc. and Hibernate Authors
+ */
+package org.hibernate.orm.test.jpa.xml;
+
+import jakarta.persistence.Id;
+import jakarta.persistence.Version;
+
+import java.util.List;
+
+public class Consumer {
+
+ @Id
+ private int id;
+
+ private List consumerItems;
+
+ @Version
+ private int version;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public List getConsumerItems() {
+ return consumerItems;
+ }
+
+ public void setConsumerItems(List consumerItems) {
+ this.consumerItems = consumerItems;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setVersion(int version) {
+ this.version = version;
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/ConsumerItem.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/ConsumerItem.java
new file mode 100644
index 000000000000..d984e44f275f
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/ConsumerItem.java
@@ -0,0 +1,41 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright Red Hat Inc. and Hibernate Authors
+ */
+package org.hibernate.orm.test.jpa.xml;
+
+import jakarta.persistence.Version;
+
+public class ConsumerItem {
+
+ private int id;
+
+ private Consumer consumer;
+
+ @Version
+ private int version;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public Consumer getConsumer() {
+ return consumer;
+ }
+
+ public void setConsumer(Consumer consumer) {
+ this.consumer = consumer;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setVersion(int version) {
+ this.version = version;
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/ExplicitOptimisticLockAnnotationOnCollectionXmlOnlyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/ExplicitOptimisticLockAnnotationOnCollectionXmlOnlyTest.java
new file mode 100644
index 000000000000..8aae05a896ee
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/ExplicitOptimisticLockAnnotationOnCollectionXmlOnlyTest.java
@@ -0,0 +1,82 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright Red Hat Inc. and Hibernate Authors
+ */
+package org.hibernate.orm.test.jpa.xml;
+
+import org.hibernate.testing.jdbc.SQLStatementInspector;
+import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
+import org.hibernate.testing.orm.junit.JiraKey;
+import org.hibernate.testing.orm.junit.Jpa;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+
+
+@JiraKey(value = "HHH-19528")
+@Jpa(
+ xmlMappings = {"org/hibernate/orm/test/jpa/xml/ExplicitOptimisticLockAnnotationOnCollectionXmlOnlyTest.xml"},
+ useCollectingStatementInspector = true
+)
+class ExplicitOptimisticLockAnnotationOnCollectionXmlOnlyTest {
+
+ private static SQLStatementInspector statementInspector;
+ private static int consumerId;
+
+
+ @BeforeEach
+ public void setUp(EntityManagerFactoryScope scope) {
+ statementInspector = scope.getCollectingStatementInspector();
+
+ scope.inTransaction( em -> {
+ Consumer consumer = new Consumer();
+ em.persist( consumer );
+ consumerId = consumer.getId();
+
+ ConsumerItem item1 = new ConsumerItem();
+ item1.setConsumer( consumer );
+ em.persist( item1 );
+
+ ConsumerItem item2 = new ConsumerItem();
+ item2.setConsumer( consumer );
+ em.persist( item2 );
+ } );
+ }
+
+ @Test
+ void test(EntityManagerFactoryScope scope) {
+ statementInspector.clear();
+
+ scope.inTransaction( em -> {
+ Consumer consumer = em.find( Consumer.class, consumerId );
+ ConsumerItem inventory = new ConsumerItem();
+ inventory.setConsumer( consumer );
+ consumer.getConsumerItems().add( inventory );
+ } );
+ statementInspector.assertUpdate();
+ statementInspector.assertInsert();
+ }
+
+ @Test
+ void testVersionOnMappedSupertype(EntityManagerFactoryScope scope) {
+ var shop = scope.fromTransaction( em -> {
+ Supermarket supermarket = new Supermarket();
+ supermarket.setName( "Tesco" );
+ em.persist( supermarket );
+ return supermarket;
+ } );
+
+ statementInspector.clear();
+ scope.inTransaction( em -> {
+ Supermarket supermarket = em.find( Supermarket.class, shop.getId() );
+ supermarket.setName( "Leclerc" );
+ } );
+ scope.inTransaction( em -> {
+ Supermarket supermarket = em.find( Supermarket.class, shop.getId() );
+ assertThat( shop.getVersion() ).isNotEqualTo( supermarket.getVersion() );
+ } );
+
+ statementInspector.assertHasQueryMatching( "update.*version.*" );
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/NoDefaultOptimisticLockAnnotationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/NoDefaultOptimisticLockAnnotationTest.java
new file mode 100644
index 000000000000..425937965357
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/NoDefaultOptimisticLockAnnotationTest.java
@@ -0,0 +1,60 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright Red Hat Inc. and Hibernate Authors
+ */
+package org.hibernate.orm.test.jpa.xml;
+
+import org.hibernate.testing.jdbc.SQLStatementInspector;
+import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
+import org.hibernate.testing.orm.junit.JiraKey;
+import org.hibernate.testing.orm.junit.Jpa;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+
+@JiraKey(value = "HHH-19495")
+@Jpa(
+ xmlMappings = {"org/hibernate/orm/test/jpa/xml/NoDefaultOptimisticLockAnnotationTest.xml"},
+ annotatedClasses = {Consumer.class, ConsumerItem.class},
+ useCollectingStatementInspector = true
+)
+class NoDefaultOptimisticLockAnnotationTest {
+
+ private static SQLStatementInspector statementInspector;
+ private static int consumerId;
+
+
+ @BeforeEach
+ public void setUp(EntityManagerFactoryScope scope) {
+ statementInspector = scope.getCollectingStatementInspector();
+
+ scope.inTransaction( em -> {
+ Consumer consumer = new Consumer();
+ em.persist( consumer );
+ consumerId = consumer.getId();
+
+ ConsumerItem item1 = new ConsumerItem();
+ item1.setConsumer( consumer );
+ em.persist( item1 );
+
+ ConsumerItem item2 = new ConsumerItem();
+ item2.setConsumer( consumer );
+ em.persist( item2 );
+ } );
+ }
+
+ @Test
+ void test(EntityManagerFactoryScope scope) {
+ statementInspector.clear();
+
+ scope.inTransaction( em -> {
+ Consumer consumer = em.find( Consumer.class, consumerId );
+ ConsumerItem inventory = new ConsumerItem();
+ inventory.setConsumer( consumer );
+ consumer.getConsumerItems().add( inventory );
+ } );
+
+ statementInspector.assertIsInsert( 1 );
+ statementInspector.assertNoUpdate();
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/Supermarket.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/Supermarket.java
new file mode 100644
index 000000000000..f520b6469db7
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/xml/Supermarket.java
@@ -0,0 +1,18 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright Red Hat Inc. and Hibernate Authors
+ */
+package org.hibernate.orm.test.jpa.xml;
+
+public class Supermarket extends BaseShop {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/hibernate-core/src/test/resources/org/hibernate/orm/test/jpa/xml/ExplicitOptimisticLockAnnotationOnCollectionXmlOnlyTest.xml b/hibernate-core/src/test/resources/org/hibernate/orm/test/jpa/xml/ExplicitOptimisticLockAnnotationOnCollectionXmlOnlyTest.xml
new file mode 100644
index 000000000000..4ea384661d8a
--- /dev/null
+++ b/hibernate-core/src/test/resources/org/hibernate/orm/test/jpa/xml/ExplicitOptimisticLockAnnotationOnCollectionXmlOnlyTest.xml
@@ -0,0 +1,67 @@
+
+
+
+
+ org.hibernate.orm.test.jpa.xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hibernate-core/src/test/resources/org/hibernate/orm/test/jpa/xml/NoDefaultOptimisticLockAnnotationTest.xml b/hibernate-core/src/test/resources/org/hibernate/orm/test/jpa/xml/NoDefaultOptimisticLockAnnotationTest.xml
new file mode 100644
index 000000000000..92dbdabbb6ae
--- /dev/null
+++ b/hibernate-core/src/test/resources/org/hibernate/orm/test/jpa/xml/NoDefaultOptimisticLockAnnotationTest.xml
@@ -0,0 +1,52 @@
+
+
+
+
+ org.hibernate.orm.test.jpa.xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/SQLStatementInspector.java b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/SQLStatementInspector.java
index d5c42adc15e9..a322069b3cab 100644
--- a/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/SQLStatementInspector.java
+++ b/hibernate-testing/src/main/java/org/hibernate/testing/jdbc/SQLStatementInspector.java
@@ -127,7 +127,19 @@ public void assertUpdate() {
.anySatisfy( sql -> Assertions.assertThat( sql.toLowerCase( Locale.ROOT ) ).startsWith( "update" ) );
}
+ public void assertInsert() {
+ Assertions.assertThat( sqlQueries )
+ .isNotEmpty()
+ .anySatisfy( sql -> Assertions.assertThat( sql.toLowerCase( Locale.ROOT ) ).startsWith( "insert" ) );
+ }
+
public static SQLStatementInspector extractFromSession(SessionImplementor session) {
return (SQLStatementInspector) session.getJdbcSessionContext().getStatementInspector();
}
+
+ public void assertHasQueryMatching(String queryPattern) {
+ Assertions.assertThat( sqlQueries )
+ .isNotEmpty()
+ .anySatisfy( sql -> Assertions.assertThat( sql.toLowerCase( Locale.ROOT ) ).matches( queryPattern ) );
+ }
}