versant jpa developer's guide

210
Versant JPA Developer's Guide Release 2.0

Upload: duongtuyen

Post on 04-Jan-2017

309 views

Category:

Documents


2 download

TRANSCRIPT

Versant JPA Developer's Guide

Release 2.0

Versant JPA Developer's Guide: Release 2.0Versant JPA2.0.17

Copyright © 2012–2015 Versant Software LLC and Copyright © 2013–2015 Actian Corporation. All rights reserved.

The software described in this document is subject to changewithout notice. This document does not represent a commitmenton the part of Versant or Actian. The software is furnished under a license agreement or nondisclosure agreement and maybe used or copied only in accordance with the terms of the agreement. No part of this manual may be reproduced ortransmitted in any formor by anymeans, electronic ormechanical, including photocopying and recording, or for any purposewithout the express written permission of Actian.

Versant JPA uses functionality provided in libraries supplied by third parties. License agreements for these third partylibraries are provided along with the libraries in the lib directory in the Versant JPA installation.

Versant, Versant Object Database and FastObjects are either registered trademarks or trademarks of Versant Software LLCin the United States and/or other countries.

Java and all Java-based marks are trademarks or registered trademarks of Oracle Corporation in the United States and othercountries.

Microsoft and Windows are trademarks of Microsoft Corporation in the United States and/or other countries.

Linux® is the registered trademark of Linus Torvalds in the United States and other countries.

Red Hat, Red Hat Enterprise Linux, and JBoss are trademarks of Red Hat, Inc., registered in the United States and othercountries.

Eclipse is a trademark of Eclipse Foundation, Inc.

All other products are a registered trademark or trademark of their respective company in the United States and/or othercountries.

2015-V13-2

Table of ContentsLinks ................................................................................................................................... ixIntroduction ........................................................................................................................ xiI. V/JPA Programming ........................................................................................................... 1

1. Persistence Unit Configuration ................................................................................... 31.1. Persistence Unit Settings ................................................................................. 31.2. Versant JPA Vendor-specific Properties ............................................................. 4

1.2.1. Connections ......................................................................................... 51.2.2. User Authorization ............................................................................... 81.2.3. Automatic Reconnect ......................................................................... 101.2.4. Schema Handling ............................................................................... 111.2.5. Indexing ............................................................................................ 141.2.6. Performance ....................................................................................... 161.2.7. Queries .............................................................................................. 181.2.8. Entity Reference Handling .................................................................. 201.2.9. In-memory XML Metadata .................................................................. 221.2.10. General ............................................................................................ 24

1.3. Property Index .............................................................................................. 272. Naming Conventions ................................................................................................ 31

2.1. Entity Names ................................................................................................ 312.2. Entity Attributes ........................................................................................... 33

3. Enhancing Your Entity Classes .................................................................................. 353.1. The Enhancement Process ............................................................................. 353.2. Run-time Enhancement ................................................................................. 373.3. Build-time Enhancement—The Enhancer Ant Task .......................................... 383.4. Build-time Enhancement—The Java Executable Enhancer ................................ 41

4. Versant JPA Server Administration API ...................................................................... 455. Distributed Databases .............................................................................................. 476. Second-level Cache .................................................................................................. 51

6.1. Configuration ............................................................................................... 516.2. Pluggable Cache ............................................................................................ 52

6.2.1. Ehcache ............................................................................................. 526.2.2. Infinispan .......................................................................................... 54

7. Automatic Flushing .................................................................................................. 578. Using an Application Server ...................................................................................... 59

8.1. Setting up JBoss ............................................................................................ 598.2. JBoss Applications ......................................................................................... 608.3. Transaction Manager Discovery ..................................................................... 618.4. XA Transactions with JBoss ............................................................................ 618.5. Restrictions .................................................................................................. 63

iiiVersant JPA Developer's Guide

9. Transactions ............................................................................................................ 659.1. Resource-local Native Transactions ................................................................ 659.2. Distributed Native Transactions ..................................................................... 669.3. XA Distributed Transactions .......................................................................... 689.4. Identifying Dead Transactions ....................................................................... 68

10. Schema Evolution .................................................................................................. 7110.1. Enabling Schema Evolution .......................................................................... 7110.2. Fields .......................................................................................................... 7210.3. Class Hierarchy ........................................................................................... 78

11. Application Evolution ............................................................................................ 8711.1. Using Application Evolution ......................................................................... 8711.2. Schema Loose Mapping ............................................................................... 89

11.2.1. Enabling Schema Loose Mapping ....................................................... 9011.2.2. Schema Compatibility for Loose Mapping ........................................... 9111.2.3. Default Values for Added/Removed Fields .......................................... 9211.2.4. Examples ......................................................................................... 92

12. Entity Identity ....................................................................................................... 9512.1. Allocation of Logical Object Identifiers ......................................................... 9512.2. Using the Entity Identifier in Queries ........................................................... 97

13. Collections and Maps ............................................................................................. 9913.1. Collection Optimization ............................................................................... 9913.2. Map Behavior ............................................................................................ 100

14. Fetch Strategies ................................................................................................... 10314.1. Eager loading ............................................................................................ 10314.2. Entity Graphs ............................................................................................ 10414.3. Burst-Fetch ............................................................................................... 105

15. Unresolvable References ....................................................................................... 10915.1. Repairing Unresolvable References ............................................................. 10915.2. Monitoring Unresolvable References ........................................................... 11115.3. Custom Handling of Unresolvable References .............................................. 113

16. Large Objects ....................................................................................................... 11717. Indexes ................................................................................................................ 119

17.1. Index Annotations ..................................................................................... 11917.2. Multiple Indexes ........................................................................................ 12017.3. Index Definition File .................................................................................. 12117.4. Index Inheritance ....................................................................................... 12117.5. Indexing Inherited Attributes ..................................................................... 12217.6. Building Index Meta Data From Annotations ............................................... 12317.7. Building Index Meta Data From an Index Definition File ............................... 12417.8. Database Index Synchronization, Creation and Evolution ............................. 124

18. Handling Large Query Results—Cursor Queries ...................................................... 12719. Application Monitoring ........................................................................................ 129

Versant JPA Developer's Guideiv

19.1. Logging ..................................................................................................... 12919.1.1. XA Resource Logging ...................................................................... 130

19.2. Monitoring Using JMX ............................................................................... 13019.2.1. Enabling JMX .................................................................................. 13119.2.2. Accessing JMX MBeans .................................................................... 13219.2.3. V/JPA MBean Data .......................................................................... 13319.2.4. The V/JPA Client MBeans ................................................................ 134

19.2.4.1. Databases ............................................................................ 13419.2.4.2. Entity Manager Factory ........................................................ 13819.2.4.3. Cache .................................................................................. 139

19.2.5. The V/JPA Server MBeans ................................................................ 14019.3. Session Name ............................................................................................ 141

20. Automatic Client Reconnect ................................................................................. 14320.1. Reconnect Properties ................................................................................. 14420.2. Exception Handling—JSE Applications ........................................................ 14420.3. Exception Handling—JEE Containers .......................................................... 14620.4. Reconnect Listener .................................................................................... 147

21. The Generic API ................................................................................................... 149II. Versant JPA and the JPA Specification ............................................................................. 155

22. Restrictions .......................................................................................................... 15722.1. Annotations .............................................................................................. 15722.2. Data Types ................................................................................................ 15722.3. Queries ..................................................................................................... 158

23. Versant JPA Implementations ................................................................................ 15923.1. Primary Keys and Object Identifiers ............................................................ 15923.2. Mapping ................................................................................................... 16023.3. Entity Graphs ............................................................................................ 160

23.3.1. Implementation .............................................................................. 16123.3.2. Clarification ................................................................................... 162

23.4. Normalization ........................................................................................... 16223.5. Flush Operations ....................................................................................... 16323.6. Entity Class Enhancement .......................................................................... 16423.7. Cascading Persistence ................................................................................ 16523.8. The Entity Manager find() Method ............................................................ 16523.9. Query Support ........................................................................................... 16623.10. Object Cloning ......................................................................................... 16623.11. Entity Lifecycle Listeners .......................................................................... 16723.12. Locking and Concurrency Control ............................................................. 16723.13. Mapped Superclasses ............................................................................... 16923.14. Serializable Fields .................................................................................... 17023.15. XAResource Implementation ..................................................................... 170

vVersant JPA Developer's Guide

24. Currently Supported Features ............................................................................... 17124.1. JPA Features .............................................................................................. 17124.2. JPQL Support ............................................................................................. 172

25. JPA Public API Support ......................................................................................... 17725.1. Package javax.persistence ....................................................................... 177

25.1.1. Primary Persistence Interfaces ......................................................... 17725.1.2. Query-related Interfaces ................................................................. 181

25.2. Package javax.persistence.spi ................................................................. 18425.3. Package javax.persistence.criteria ........................................................ 18525.4. Package javax.persistence.metamodel ....................................................... 18525.5. Annotations .............................................................................................. 185

25.5.1. Vendor-specific Annotations ........................................................... 18525.5.2. JPA Annotation Support .................................................................. 186

A. Server Statistics Reference ............................................................................................. 193A.1. Database Statistic Names .................................................................................... 193

Versant JPA Developer's Guidevi

List of Tables3.1. V/JPA Enhancer ant Task Attributes & Elements ............................................................. 393.2. V/JPA Enhancer Class EnhancerMain Arguments .............................................................. 4213.1. @EqualsById—Supported Classes and Methods .......................................................... 10020.1. ReconnectFailStatus Enumeration Values .................................................................. 14524.1. JPQL—Supported Expressions in V/JPA ....................................................................... 17324.2. JPQL—Unsupported Expressions in V/JPA ................................................................... 17425.1. Interface EntityManager ............................................................................................. 17725.2. Interface EntityManagerFactory ................................................................................. 17925.3. Interface EntityTransaction ...................................................................................... 18025.4. Interface Cache .......................................................................................................... 18025.5. Interface PersistenceUnitUtil ................................................................................... 18025.6. Interface PersistenceUtil ......................................................................................... 18025.7. Class Persistence ...................................................................................................... 18125.8. Interface Query .......................................................................................................... 18125.9. Interface TypedQuery<X> ............................................................................................. 18325.10. Interface Parameter<T> ............................................................................................. 18325.11. Interface Tuple ........................................................................................................ 18425.12. Interface TupleElement<X> ........................................................................................ 18425.13. Interface Summary—javax.persistence.spi ............................................................. 18425.14. Class Summary—javax.persistence.spi .................................................................. 18525.15. Annotations ............................................................................................................ 186A.1. Names of Database Statistics ....................................................................................... 193

viiVersant JPA Developer's Guide

Versant JPA Developer's Guideviii

Links

Download Versant JPA

Download the latest V/JPA release.

esd.actian.com/product/Versant_JPA/2.0

V/JPA Support

If you have questions or need help using V/JPA, you can get quick answers. Contact the V/JPAdevelopment staff.

[email protected]

V/JPA Forum

Stay in touch with the development team and with other V/JPA developers at the V/JPA Forum.

www.versant.com/jpa-forum

Actian Web Site

For the latest Actian corporate and product news, visit the Actian web site.

www.actian.com/

Actian Versant Products

Contact us with your inquiries about Versant products and services.

[email protected]

ixVersant JPA Developer's Guide

Actian Office Locations

Actian Corporation is headquartered in Redwood City, California.

Versant GmbH is responsible for European operations and has offices in Hamburg, Germany.

Actian Corporate Headquarters

500 Arguello Street, Suite 200Redwood City, CA 94063USA

+1.650.587.5500 [TEL]+1.650.587.5550 [FAX]

Versant GmbH

Halenreie 42D-22359 HamburgGermany

+49 (0)40 609 90 0 [TEL]+49 (0)40 609 90 113 [FAX]

Contact us with feedback regarding this guide.

[email protected]

Versant JPA Developer's Guidex

IntroductionSystem RequirementsDocument ConventionsNew in Release 2.0

This guide provides you with information about the features and capabilities of Versant's JavaPersistence API (JPA) data persistence solution, Versant JPA. If you are new toV/JPA, we recommendyou work through the step-by-step tutorial. Follow the steps in the Versant JPA Tutorial (in the docdirectory) to create your first real Versant JPA application.

In addition to the step-by-step tutorial, youwill find other examples in the vjpa2/examples directoryin your V/JPA installation. These include a simple “Hello World” example(vjpa2/examples/jpa_hello_world; running this is a good way to see that Versant JPA is correctlyinstalled), an example demonstrating attibute indexing in V/JPA (vjpa2/examples/jpa_indexing),another showing theV/JPA generic API (vjpa2/examples/jpa_generic_api), a simple Java EnterpriseEdition project showing how to install and run a V/JPA application within the JBoss applicationserver (vjpa2/examples/jpa_jboss) and a number of other examples. Just follow the directions inthe readme file that accompanies each example.

For information about programming with Versant JPA Server, including discussions regardingindexing and the generic API interfacementioned above, refer to Part I, “V/JPA Programming” pg. 1.Also, you will find the Javadoc API reference for Versant JPA, including the complete JPA standardAPI, in vjpa2/doc/javadoc/index.html in your V/JPA installation.

If you already have some experiencewith JPA you'll want to read the section detailing the differencesbetween the JPA specification and the Versant JPA implementation. V/JPA follows the specificationquite closely but you will want to be aware of the differences and the areas that have yet to be fullyimplemented. All of this is described in Part II, “Versant JPA and the JPA Specification” pg. 155.(You JPA newbies may want to refer to that section when you are a bit more familiar with JPA.)

Minimum System Requirements

Versant JPA has the following minimum requirements for your development system.

Java SDK

Java Platform, Standard or Enterprise Edition (Java SE or EE) 7

xiVersant JPA Developer's Guide

Eclipse IDE

Eclipse 3.8.2 (V/JPA does not require Eclipse but does provide an Eclispe Plug-in and numerousEclipse-based examples)

Document Conventions

Notes, Tips, Important information

Occasionally, you are provided with additional information regarding a topic. These notes, tips,etc. are set apart from the text and the kind of information presented is indicated by various symbolsas follows.

A note supplies you with additional information about a topic. Thisinformation can help explain how somethingworks or provide backgroundto help you better understand the topic.

Note

A tip is an extra bit of information to give you an insight into how aparticular feature or API can be applicable to your applicationdevelopment.

Tip

Important means just that. The information given should be followed.This can be a particular setup necessary to use a feature, for example.

Important

Warnings let you know that there are potential consequences to using aparticular utilitiy or API, for example, itmay be a caution tomake a backupbefore running a utility.

Warning

Introduced in Versant JPA Release 2.0

V/JPA 2.0 adds functionality such as support for enterprise production environments, distributedcaching, and support for high-availability environments. The following lists the major featuresadded in V/JPA 2.0.

• Support for Second-level Cache

V/JPA provides a pluggable cache mechanism allowing you to use a third-party cacheimplementation.Refer to Chapter 6, Second-level Cache pg. 51

• JEE Suppport

Versant JPA Developer's Guidexii

You can use V/JPA with the JBoss application server.Refer to Chapter 8, Using an Application Server pg. 59

• Runtime Schema Evolution

V/JPA's application evolution allows your clients to be updated over time, while still continuingto run using an evolved database.Refer to Chapter 11, Application Evolution pg. 87

• Burst Fetch

A smart fetch strategy for loading referenced entities of a given entity class.Refer to Section 14.3, “Burst-Fetch” pg. 105

• Large Object Support

V/JPA 2.0 now provides support for the @Lob annotation.Refer to Chapter 16, Large Objects pg. 117

• Client Auto-Reconnect

As part of V/JPA's support for high-availability environments, clients can automatically reconnectto the V/JPA server following a failover or other interruption.Refer to Chapter 20, Automatic Client Reconnect pg. 143

V/JPA complies with the JPA 2.0 standard. Details of the V/JPA implementation can be found inPart II, “Versant JPA and the JPA Specification” pg. 155. The following lists new functionality addedin release 2.0.

• Lifecycle listeners

Refer to Section 23.11, “Entity Lifecycle Listeners” pg. 167

• Mapped superclasses

Refer to Section 23.13, “Mapped Superclasses” pg. 169

• Serializable fields

Refer to Section 23.14, “Serializable Fields” pg. 170

xiiiVersant JPA Developer's Guide

Versant JPA Developer's Guidexiv

Part I. V/JPA Programming

Chapters• Persistence Unit Configuration• Naming Conventions• Enhancing Your Entity Classes• Versant JPA Server Administration API• Distributed Databases• Second-level Cache• Automatic Flushing• Using an Application Server• Transactions• Schema Evolution• Application Evolution• Entity Identity• Collections and Maps• Fetch Strategies• Unresolvable References• Large Objects• Indexes• Handling Large Query Results—Cursor Queries• Application Monitoring• Automatic Client Reconnect• The Generic API

This section discusses additional features and programming support provided by Versant JPA.

API Reference—JPA and V/JPA

The complete Javadoc API reference for JPA and V/JPA is provided in your V/JPA installation. Openthe file vjpa2/javadoc/index.html in your browser.

Chapter 1. Persistence Unit Configuration

Sections• Persistence Unit Settings• Versant JPA Vendor-specific Properties

- Connections- User Authorization- Automatic Reconnect- Schema Handling- Indexing- Performance- Queries- Entity Reference Handling- In-memory XML Metadata- General

• Property Index

The JPA persistence unit configuration is defined in a file named persistence.xml. This chapterprovides information about the persistnce unit settings when using V/JPA. The numerousvendor-specific persistence unit properties for extended V/JPA functionality are also described.

1.1. Persistence Unit SettingsVersant JPA currently interprets only a sub-set of the possible standard JPA settings in thepersistence unit configuration file (persistence.xml). V/JPA will ignore settings that it doesn'tunderstand, so long as they are syntactically correct.

The following shows a sample persistence unit configuration file as it might look for V/JPA.

persistence.xml<persistence version="2.0">

<persistence-unit name="jpa_tutorial_persistence_unit" transaction-type="RESOURCE_LOCAL">

<class>com.versant.jpa.tutorial.model.Person</class>

3Versant JPA Developer's Guide

<class>com.versant.jpa.tutorial.model.Book</class>

<properties>

<property name="versant.connectionURL" value="jpa_tutorial@localhost" />

</properties>

</persistence-unit>

</persistence>

Required Settings

• For runtime enhancement and by default in a JSE environment a <class> element must bespecified, with fully-qualified package names, for every entity class. (Refer to Chapter 3, EnhancingYour Entity Classes pg. 35 for details.)

• The vendor-specific property versant.connectionURLmust be set and the specified databasemust exist. (Refer to versant.connectionURL pg. 7.)

1.2. Versant JPA Vendor-specific PropertiesThe following sections list and describe the V/JPA vendor-specific properties. The properties areorganized into functional categories in the following sections.

• Connections

• User Authorization

• Automatic Reconnect

• Schema Handling

• Indexing

• Performance

• Queries

• Entity Reference Handling

Versant JPA Developer's Guide4

Versant JPA Vendor-specific Properties

• In-memory XML Metadata

• General

Refer to the Section 1.3, “Property Index” pg. 27 at the end of this chapter for a list of all of theavailable vendor-specific properties.

1.2.1. Connections

versant.connectionIdleTimeout

If a connection is returned to the connection pool, all available connections (i.e., connectionsthat are not currently in use) are examined to determine when they were last used, based ontheir timestamp, beginning with the longest unused connection. If any of these availableconnections has not been used for longer than the specified time, it will be closed (default is60 seconds).

Connections are closed until the number of remaining available connections is the value setfor the versant.coreConnectionPoolSize property (or all connections older than the specifiedtime are closed).

Setting versant.connectionIdleTimeout to 0 (zero) has the effect of maintaining the numberof connections in the pool to the value set for versant.coreConnectionPoolSize.

allowed values:

positive integer value (milliseconds)

default:

60000

versant.connectionPoolCleanupThreadSleepTime

If the value is greater than 0 (zero), a cleanup thread for all connection pools for theEntityManagerFactory instance is started. This periodically triggers a connection idle timeoutcheck. The value of this property is the time, in seconds, that the cleanup thread sleeps betweenchecks.

The result is that an idle connection is closed no earlier than the time it was last used plus thevalue of connectionIdleTimeout and no later than that time plus the value ofconnectionPoolCleanupThreadSleepTime.

5Versant JPA Developer's Guide

Versant JPA Vendor-specific Properties

That is, an idle connection is closed at time t, where:

tlast-used+connectionIdleTimeout <= t <= tlast-used+connectionIdleTimeout+connectionPoolCleanupThreadSleepTime

Idle connections are not closed if the pool size has already been reduced to the value ofcoreConnectionPoolSize.

allowed values:

positive integer value (seconds)

default:

0

versant.connectionPoolMaxWaitTime

If a new connection cannot be allocated because there are no available connections in theconnection pool, by default, the requesting transaction will immediately receive an errorexception. The versant.connectionPoolMaxWaitTime property can be used to specifiy a waittime for a connection to become available before an exception is thrown. The wait time isspecified in milliseconds. Specifying 0 (zero), the default value, indicates no wait time. Anexception is thrown immediately following a failed request. You can also specify -1 to waitindefinitely for a connection to become available.

allowed values:

integer value >= 0 (milliseconds) or -1

default:

0

versant.connectionPoolSize

This property determines the maximum number of available connections in the connectionpool for a given entity manager factory. A connection is taken from the pool for the durationof the database transaction. For example, you could create any number of entity managerswithout impact on the connection pool but only have active transactions on thenumber specifiedfor the pool.

allowed values:

positive integer value > 0

Versant JPA Developer's Guide6

Versant JPA Vendor-specific Properties

default:

10

versant.connectionURL

The name(s) of the database(s) to connect to.

For a single database the URL should be of the form

versant:database@host:port

For multiple databases, use the same URL syntax for each database and separate the URLs withthe | character

versant:database1@host1:port1|versant:database2@host2:port2

The URL scheme versant: is optional. The parts of the URL are described below.

Name limitations

Only characters from the US-ASCII character set are allowed in database and host names.Additionally, the combined database name and host name (including the @ character) is limitedto a length of 255 characters. This length limitation applies to the databaseName@hostNameportion of the URL and also includes the scheme name (versant:) or port (:port) components,if used. Note that databaseName itself is limited to a maximum length of 31 characters.

database

The name of the database. This is required.

host

This is the host name of the database server.

port

This is the port to be used to establish a connection to the database. This is optional. If notspecified it defaults to 5019, the port typically used by Versant JPA Server.

allowed values:

7Versant JPA Developer's Guide

Versant JPA Vendor-specific Properties

integer

default:

5019

versant.coreConnectionPoolSize

This property determines the minimum number of available connections to keep in theconnection pool when removing connections that have not been used based on the value ofversant.connectionIdleTimeout. The value of this property defaults to the value ofversant.connectionPoolSize.

allowed values:

integer value between 1 and the value of versant.connectionPoolSize, inclusive

default:

value of versant.connectionPoolSize

versant.sessionName

Specifies a session name for the entity manager factory. The Versant JPA Server will displaythis namewhen reporting information about database connections and transactions associatedwith the factorymanagers. Refer to Section 19.3, “SessionName” pg. 141 formore information.

allowed values:

string value, maximum length 63 characters

default:

"V/JPA"

1.2.2. User Authorization

By default, when opening a V/JPA database, the system user name (with no password) is used. Thefollowing properties allow you to specify the user name and password for the database(s) used byyour application. The basic form to use these properties is as follows.

Versant JPA Developer's Guide8

Versant JPA Vendor-specific Properties

<persistence-unit name="singleDatabase">. . .<properties><property name="versant.connectionURL" value="dbA@localhost"><property name="versant.username" value="User1"><property name="versant.password" value="a1b2c3">

</properties></persistence-unit>

If you are using distributed databases (refer to Chapter 5, Distributed Databases pg. 47) you canspecify a list of user names or passwords. Separate the user names and passwords using the |character as you would for the database names. Here is an example.

<persistence-unit name="distributedDatabase">. . .<properties><property name="versant.connectionURL"

value="dbA@localhost|dbB@localhost|dbC@localhost"><property name="versant.username" value="User1|User2|User3"><property name="versant.password" value="a1b2c3|d4e5f6|g7h8i9">

</properties></persistence-unit>

You can leave out a user name or password in the list if the corresponding database does not requireit. For example, value="User1||User3". Also, you can specify a single user name or password to beused for all of the databases in the versant.connectionURL list.

User Authorization Properties

versant.password

Specifies the password for the database specified by the versant.connectionURL property. Ifyou are using distributed databases, the passwords are specified as a |-delimited list. A singlepassword to be used for all databases may also be specified.

allowed values:

a string specifying the password(s)

default:

9Versant JPA Developer's Guide

Versant JPA Vendor-specific Properties

none

versant.username

Specifies the user name for the database specified by the versant.connectionURL property. Ifyou are using distributed databases, the user names are specified as a |-delimited list. A singleuser name to be used for all databases may also be specified.

allowed values:

a string specifying the user name(s)

default:

the system user

1.2.3. Automatic Reconnect

versant.reconnectCount

Specifies the number of times a client entity manager factory will attempt to reconnect to theVersant JPA Server following a connection loss. The default setting is 0 (zero) meaning noreconnect attempt is made. You can also specify the time between reconnect attempts withthe versant.reconnectWait property.

Refer to Chapter 20, Automatic Client Reconnect pg. 143 for more information.

allowed values:

non-negative integer value

default:

0 (no reconnect attempt)

versant.reconnectListener

Specifies a reconnect listener for automatic client reconnect notifications. The listener is aclass that implements the ReconnectListener interface. Only one reconnect listener may beregistered in a persistence unit. (Additional listeners, if needed, may be registered with thepersistence manager factory.) Refer to Chapter 20, Automatic Client Reconnect pg. 143 and

Versant JPA Developer's Guide10

Versant JPA Vendor-specific Properties

Section 20.4, “Reconnect Listener” pg. 147 for more information. Also refer toversant.reconnectCount.

allowed values:

string naming a class implementation of the ReconnectListener interface

default:

none

versant.reconnectWait

Specifies the time, in milliseconds, between client reconnect attempts. Refer toversant.reconnectCount.

allowed values:

positive integer value (milliseconds)

default:

100

1.2.4. Schema Handling

versant.schemaDefine

This property determines whether new schema classes will be defined as needed at runtime byV/JPA. The default value is true.

Before the instances of a entity class can be stored in a V/JPA Server database, a schema forthe class must first be defined in the database.

This schemadefinition process is executed at runtimewhen instantiating aV/JPA entitymanagerfactory (by calling Persistence.createEntityManagerFactory()).

The schema definition process is not thread-safe. You must insure that multiple user threadsdo not try to define the schema for the same classes simultaneously (i.e., by synchronizing yourcreateEntityManagerFactory() calls).

This property must be set to false if loose schema mapping is used.

11Versant JPA Developer's Guide

Versant JPA Vendor-specific Properties

allowed values:

true, false

default:

true

versant.schemaEvolve

Determines whether datastore schemawill be evolved if required. The default value for the flagis false, i.e., schemawill not be evolved in the case of amismatch. Refer to Chapter 10, SchemaEvolution pg. 71 for more information and examples of schema evolution.

This property must be set to false if schema loose mapping is used.

allowed values:

true, false

default:

false

versant.schemaLooseMapping

Schema loose mapping is a mechanism that will allow limited mis-matches in client/serverschemas. Refer to Section 11.2, “Schema Loose Mapping” pg. 89 for information.

This property cannot be used (or must be set to off) if schema definition or schema evolutionis used.

allowed values:

offruntimestartupruntime_preserve_valuesstartup_preserve_values(These are described in Section 11.2.1, “Enabling Schema Loose Mapping” pg. 90.)

default:

off

Versant JPA Developer's Guide12

Versant JPA Vendor-specific Properties

versant.schemaLooseSyncTimeout

This property applies to the situation when clients are using application evolution and schemaloosemappingwithin amultiple database network. Refer to Chapter 11,Application Evolution pg.87 and Section 11.2, “Schema Loose Mapping” pg. 89.

In a typical application evolution (schema loose mapping) scenario where clients connect tomultiple databases, a single client will work with schema evolution and initiate the schemaupdate in the appropriate databases. The time necessary for the change to propagate to all ofthe databases will vary depending on the number of databases involved and other factors suchas network performance. As the other clients, using loose mapping, connect to the databases,theywill detect the schemamis-match and begin a transfer of the updated schema information.

However, because of the time needed for all of the databases in the network to share the newupdated schema, a client using loosemappingmayhave detected amis-match fromonedatabaseand be in the process of updating, or even completed updating, before all of the databases havethe new schema. When the client later connects to another database that has finally receivedthe new schema, this triggers another schema transfer. Often, this is not a concern as the timeto transfer and integrate the updated schema will be quite short. But with very large schemas,containing thousands of classes, a schema transfer can take some seconds.

The versant.schemaLooseSyncTimeout property allows you to set a timeout value to compensatefor the propagation time needed to get any schema update to all databases in the network.When a schema mis-match is detected by a client, the client will wait for the time specified bythe property before initiating the schema transfer. During this time, the other databases specifiedin the persistence unit are polled regarding their schema versions. Polling continues until theschema change has been detected in all databases or the specified timeout is reached.

With this mechanism, multiple transfers for a single multi-database schema change can bereduced or avoided—at the cost of idle wait time during the given timeout period.

If schema loose mapping is not enabled this property has no effect.

allowed values:

positive integer (number of milli-seconds)

default:

0

13Versant JPA Developer's Guide

Versant JPA Vendor-specific Properties

1.2.5. Indexing

versant.indexDefine

Set this property to false to prohibit definition of new indexes specified via annotations orexternal index files. The default value for the property is true. An index for a class is consideredas new if there is no equally named index and no B-Tree index on the same attribute sequencefor that class defined in the database.

Refer to versant.skipIndexSynchronization and Section 17.8, “Database Index Synchronization,Creation and Evolution” pg. 124.

allowed values:

true, false

default:

true

versant.indexEvolve

If this property is set to true, changes to the index definitions specified by annotations or inindex definitions files will cause existing (not new) indexes to be updated to match the newdefinition. The default value is false.

Refer to Section 17.8, “Database Index Synchronization, Creation and Evolution” pg. 124.

allowed values:

true, false

default:

false

versant.indexesDefinitionFile

Specifies the index definition file, if used, for the persistence unit. Refer to Chapter 17,Indexes pg. 119 for more information.

allowed values:

Versant JPA Developer's Guide14

Versant JPA Vendor-specific Properties

valid file path (if not absolute, the path is relative to the location of the persistence unit file)

default:

none

versant.inheritIndexes

Specifies if index definitions are inherited by sub-classes of the class for which the index isdefined. Refer to Section 17.4, “Index Inheritance” pg. 121 for more information.

allowed values:

true, false

default:

true

versant.skipIndexSynchronization

This property determines whether the application index definitions are compared to andsynchronized with the database index definitions. Setting this property to true will preventthe application index definitions being propagated to the database. This has an effect on theoperation of versant.indexDefine and versant.indexEvolve.

The versant.skipIndexSynchronization setting has no effect in the case where an index isdeleted in the database based on a schema change that invalidates the index, e.g., removingan indexed attribute (field). (This can occur if the application is using schema evolution. Referto Chapter 10, Schema Evolution pg. 71.)

Refer to Section 17.8, “Database Index Synchronization, Creation and Evolution” pg. 124 formore information.

allowed values:

true, false

default:

false

15Versant JPA Developer's Guide

Versant JPA Vendor-specific Properties

1.2.6. Performance

versant.burstFetch

Burst-fetch is a fetch strategy that automatically loads referenced entities of the same attributefor all parent entities in the current transaction and persistence context when the attribute isaccessed in any one of the parent entities. That is, if burst-fetching is enabled, when an attributeof an entity is accessed—and the attribute is not already loaded—then that same attribute isloaded (if not already) for all entities of the same type.

Refer to Section 14.3, “Burst-Fetch” pg. 105 for a more detailed description.

allowed values:

true, false

default:

false

versant.defaultLoidBatchSize

The Versant JPA datastore uses a logical object identifier, LOID, to uniquely identify the entityobject. The LOID value is also the entity primary key, the @Id field. Identifiers are allocated bythe V/JPA datastore and supplied to the entity manager factory to be assigned to newly createdentities. The datastore allocates the identifiers in batches of a specified size. The default batchsize is 1024. This property allows you to adjust the batch size to better suit the requirementsof your application. For example, if your application consistently creates very large numbersof new entities in a given transaction, that can lead tomany datastore requests for new batchesof identifiers. Adjusting the LOID batch size to a higher number may increase performance byreducing the amount of requests sent to the V/JPA server.

Use care when adjusting the LOID batch size. Small values can result in excessive numbers ofrequests and consequent server traffic. Very large values can lead to depletion of availableidentifiers in the datastore.

The LOID batch size can also be adjusted at run time for a given entity manager factory. Referto Chapter 12, Entity Identity pg. 95 for more information about object identifiers and adjustingthe LOID batch size.

allowed values:

Versant JPA Developer's Guide16

Versant JPA Vendor-specific Properties

positive integer >= 3

default:

1024

versant.flushThreshold

Specifies the number of modified (inserted, removed or deleted) objects in a transaction thatwill trigger an automatic flush operation. Setting this property to a value less than 1 disablesautomatic flushing. Refer, also, to Chapter 7, Automatic Flushing pg. 57. (Queries may exhibitdifferent behavior. Refer to the description of javax.persistence.Query.setFlushMode() inthe API reference.)

allowed values:

integer value (values < 1 disable automatic flushing)

default:

10000

versant.level2Cache

Specifies a concrete second-level cache binding by providing the fully qualified class name ofan implementation class. Optionally, the name can be followed by a colon and asemicolon-separated list of properties specific to this provider. Here is a sample format for theentry.

<property name="versant.level2Cache"value ="com.company.SomeCacheFactory:key1=value1;key2=value2" />

For information about second-level caching in V/JPA, refer to Chapter 6, Second-levelCache pg. 51.

allowed values:

string specifying a fully qualified class name and optional implementation properties

default:

none

17Versant JPA Developer's Guide

Versant JPA Vendor-specific Properties

versant.threadPoolSize

This determines whether a thread pool is used with a distributed database configuration, i.e.,if a single entity manager factory is configured to use multiple databases. If your factory onlyconnects to a single database, the value for versant.threadPoolSize has no effect. Setting thisproperty to zero (0) disables the thread-pool for multiple databases and a single threadcommunicates with all databases sequentially.

If versant.threadPoolSize is set to a value greater than zero (the default is 10), a thread poolwith the specified size is created. With a thread pool, if a request can be executed in parallelto multiple databases, the main thread communicates with the first database and passescommunication tasks to the other databases to the thread pool.

The parameter versant.connectionPoolSize determines the size of the connection pool (or thesize of each connection pool if there are multiple databases). This limits the number ofconcurrent connections from the client-side.

allowed values:

positive integer (0 disables the thread pool)

default:

10

1.2.7. Queries

versant.queryBatchSize

When a standard query is executed, the V/JPA server first transfers only the identifiers of allentities in the result set to the client. The entities themselves (the field values) are lazy-loadedin batches, as they are required, when iterating over the result set. The default batch size. i.e.,the number of entities loaded per fetch, is 10000. You can use this property to adjust the fetchedbatch size to better suit the requirements of your application.

The versant.queryBatchSize property does not apply to projection queries or cursor-querieswhich use different loading mechanisms. For a description of cursor queries, refer to Chapter 18,Handling Large Query Results—Cursor Queries pg. 127.

allowed values:

Versant JPA Developer's Guide18

Versant JPA Vendor-specific Properties

positive integer > 0

default:

10000

versant.queryInterleaveResults

When you perform a standard query, the V/JPA server first transfers only the identifiers of theresult set entities to the client. The result List collection initially only contains the identifiersand the entities themselves are lazy-loaded, in batches, as they are required. (The batch sizeis adjustable. Refer to versant.queryBatchSize.)

If you are using distributed databases (i.e., your application connects to multiple databases,refer to Chapter 5,DistributedDatabases pg. 47) the versant.queryInterleaveResults propertydetermines whether the result set of a query is interleaved (setting is true) or ordered (false,the default) with respect to the corresponding databases.

When using interleaved results (versant.queryInterleaveResults set to true) all databasesare queried concurrently when getting the next batch of entities while iterating over the resultset. Using ordered results (the default) means that the databases are queried sequentially, oneafter the other.

Using interleaved results may have a small performance impact when getting the initial resultset, but a performance improvement when loading the entities themselves, depending on thedistribution of the entities across the databases.

The versant.queryInterleaveResults property only applies to queries performed onmultipledatabases. The property does not apply to projection queries or cursor-queries which usedifferent loading mechanisms. For a description of cursor queries, refer to Chapter 18, HandlingLarge Query Results—Cursor Queries pg. 127.

allowed values:

true, false

default:

false

19Versant JPA Developer's Guide

Versant JPA Vendor-specific Properties

versant.queryTimeZone

You can use this property to specify a time zone identifier to determine the absolute time valuesof date/time literals which need to be interpreted relative to a time zone. By default, V/JPA willassume the time zone of the local (client) machine as determined by thejava.util.TimeZone.getDefault()method.

Using the default, a query for sales orders between 00:00 and 23:59 on 1/1/2013 executed froma client in Redwood City will likely return different results than the same query from a clientin Hamburg. (Of course, this may be exactly what is intended, depending on the scenario.)

With the query time zone property, you can specify what 1/1/2013, 00:00 actually means bynaming the time zone to associate with your literal time values. The time zone is given usingthe time zone identifier as specified for the java.util.TimeZone class (refer to the Java APIreference for a description of the time zone identifier format).

For the sales orders query above, your application can specify the time zone for the locationof the main office where the orders are booked, for example, and all remote sales offices willget the same query result.

allowed values:

string naming the time zone ID (refer to the java.util.TimeZone API reference)

default:

none (the time value from java.util.TimeZone.getDefault() is used)

1.2.8. Entity Reference Handling

versant.unresolvableReferenceListener

Allows you to register an implementation of a listener class for monitoring the occurences ofunresolved references. Refer to Section 15.2, “Monitoring Unresolvable References” pg. 111 forinformation about using an unresolvable reference listener.

allowed values:

string specifying the fully-qualified class name of the listener implementation

default:

Versant JPA Developer's Guide20

Versant JPA Vendor-specific Properties

none

versant.unresolvableReferenceStrategy

By default, attempting to resolve a missing or otherwise unresolvable entity reference willresult in the exception EntityNotFoundException. Setting this property to REPAIR directs V/JPAto set the offending reference to null in the case of fields or array elements or, in the case ofcollection or map elements, to remove the element.

Refer to Chapter 15, Unresolvable References pg. 109 for more information.

allowed values:

REPAIRTHROW

default:

THROW

versant.useSoftReferences

Each entitymanagermaintains amap of oject identifiers to entities. Thismap is used as a cacheto ensure that there is, at most, one entity instance for a given object identifier in the entitymanager instance. By default, this map uses java.lang.ref.WeakReference instances so thatthe garbage collector can collect otherwisenon-referencedobjects. If versant.useSoftReferencesis set to true the map will use java.lang.ref.SoftReference instances.

Regardless the setting of versant.useSoftReferences, the entity manager will hold strongreferences to all objects that have been inserted, updated or removed until they are flushed.

allowed values:

true, false

default:

false

21Versant JPA Developer's Guide

Versant JPA Vendor-specific Properties

1.2.9. In-memory XML Metadata

The following properties allow you to over-ride the metadata defined in the various XMLmetadatafiles with in-memory representations.

The XML metadata files are normally resolved in the classpath/file system based on the followingrules.

• The persistence.xml file must this name and reside in the /META-INF directory in the class path

• Mapping files can be declared in the persistence.xml, providing a path relative to thepersistence.xml's URL. In this case, it can have an arbitrary, user-defined name/path

• If no mapping file declarations are found, then default location /META-INF/orm.xml (side byside to the persistence.xml) is tried

However, there may be scenarios where you want to generate or extend this metadata informationfromyour application prior to creating the EntityManagerFactory instance. You can pass in-memoryrepresentations of the persistence/mapping files along with the optional properties map passedinto javax.persistence.Persistence.createEntityManagerFactory(String, Map) using the followingproperties.

persistence.xml overrideversant.persistence.xmlmapping file overrideversant.orm.xmlindex definition file overrideversant.indexes.xml

The values for these properties should be valid XML strings conforming to the correspondingschemata. These are described in more detail, below.

The overriding process is subject to the same set of constraints as any changes to the mappinginformation applied after the bytecode enhancement step. In particular, no information that affectsthe enhanced bytecode may be different in the in-memory version than was defined in the originalmapping information used for the enhancement step. Refer to Section 3.1, “Metadata Consistency” pg.36 for more information.

Versant JPA Developer's Guide22

Versant JPA Vendor-specific Properties

XML Metadata Override Properties

versant.indexes.xml

If set, provides an in-memory string version containing the content of a Versant JPA indexdefinition file used for creating an entity manager factory. Any index definition file declaredin the persistence.xml will be ignored.

allowed values:

a well-formed XML string that conforms to the http://versant.com/jpa/xml/indexes schema

default:

none (null)

versant.orm.xml

If set, provides an in-memory string containing the content of a mapping file (orm.xml) usedfor creating an entity manager factory. Any mapping file declared in the persistence.xml orpresent in the default location in the class path/file system will be ignored. Note that thesettings in this mapping file version must not conflict with the settings used when enhancingthe class files.

allowed values:

a well-formed XML string that conforms to the http://java.sun.com/xml/ns/persistenceschema

default:

none (null)

versant.persistence.xml

If set, provides an in-memory string containing the content of the persistence unit(persistence.xml) used for creating an entity manager factory. Any persistence.xml file on theclass path/file system will be ignored. Note that the settings in this persistence.xml versionmust not conflict with the settings used when enhancing the class files.

Declaring references to mapping/index files on the class path/file system is not supported andresults in an exception.

23Versant JPA Developer's Guide

Versant JPA Vendor-specific Properties

allowed values:

a well-formed XML string that conforms to the http://java.sun.com/xml/ns/persistenceschema

default:

none (null)

1.2.10. General

versant.defaultEntityNames

The JPA default is to use short class names in, for example, query strings. You can change thisbehavior to use fully-qualified names (with package). Refer to Section 2.1, “Entity Names” pg.31 for more information about entity naming in V/JPA.

allowed values:

JPA, default, shortClassName (these are equivalent and represent the default behavior)fullyQualifiedClassName

default:

shortClassName

versant.genericAccess

Specifies if access to the database entity objects using the V/JPA Generic API is allowed. Referto Chapter 21, The Generic API pg. 149 for more information.

allowed values:

true, false

default:

false

Versant JPA Developer's Guide24

Versant JPA Vendor-specific Properties

versant.jmx

This property determines the publishing of managed beans for JMX monitoring of the V/JPAClient (refer to Section 19.2, “Monitoring Using JMX” pg. 130). The default setting for thisproperty is false.

allowed values:

true, false

default:

false

versant.jmxServer

This property determines the publishing of managed beans for JMX monitoring of the V/JPAServer backend (refer to Section 19.2, “Monitoring Using JMX” pg. 130). The default setting forthis property is false.

allowed values:

true, false

default:

false

versant.jmxServer.username

MBeans showing server-side statistics maintain their own connection to get statistical datafrom the server. If these MBeans are enabled (by setting versant.jmxServer to true), setversant.jmxServer.username and versant.jmxServer.password if required for the connection.See also: Section 19.2, “Monitoring Using JMX” pg. 130.

allowed values:

a string specifying the username

default:

none

25Versant JPA Developer's Guide

Versant JPA Vendor-specific Properties

versant.jmxServer.password

MBeans showing server-side statistics maintain their own connection to get statistical datafrom the server. If these MBeans are enabled (by setting versant.jmxServer to true), setversant.jmxServer.username and versant.jmxServer.password if required for the connection.See also: Section 19.2, “Monitoring Using JMX” pg. 130.

allowed values:

a string specifying the password

default:

none

versant.logJpaExceptions

This property determines the reporting of V/JPA exceptions when you are using logging (referto Section 19.1, “Logging” pg. 129). The default setting for this property is false. Ifversant.logJpaExceptions is set to true, all V/JPA exceptions that are passed through theJPA-defined interfaces are logged, i.e., all EntityManager, EntityManagerFactory, Query andEntityTransaction exceptions. Be aware that this can includemany expected exceptions, suchas javax.persistence.OptimisticLockException, and can result in a large amount of loggingdata.

allowed values:

true, false

default:

false

versant.strictXmlValidation

Determineswhether an optional, strict XML validation (property value is true) or amore relaxedvalidation (false, the default) is performed for the persistence unit file and referencedmappingfiles. Strict validation uses the JPA standard XML schema which defines specific ordering forthe elements in the persistence.xml file. The relaxed schema is less strict regarding elementorder.

allowed values:

Versant JPA Developer's Guide26

Versant JPA Vendor-specific Properties

true, false

default:

false

versant.transactionManagerJndiName

V/JPA uses a list of default transaction manager names when connecting to an applicationservers. You can set this property to explicitly specify the transaction manager used with anapplication server. Refer to Section 8.3, “Transaction Manager Discovery” pg. 61.

allowed values:

a valid name for the application server transaction manager

default:

one of (depending on the application server)

(JBoss)java:/TransactionManager(GlassFish)java:appserver/TransactionManager(Resin 3.x)java:comp/TransactionManager(Borland Enterprise Server / Sun AppServer)java:pm/TransactionManager

1.3. Property IndexFollowing is an alphabetical list of the V/JPA vendor-specific properties. Click the property nameto jump to its description.

CategoryProperty NamePerformanceversant.burstFetch pg. 16

Connectionsversant.connectionIdleTimeout pg. 5

Connectionsversant.connectionPoolCleanupThreadSleepTime pg. 5

Connectionsversant.connectionPoolMaxWaitTime pg. 6

Connectionsversant.connectionPoolSize pg. 6

Connectionsversant.connectionURL pg. 7

Connectionsversant.coreConnectionPoolSize pg. 8

27Versant JPA Developer's Guide

Property Index

CategoryProperty NameGeneralversant.defaultEntityNames pg. 24

Performanceversant.defaultLoidBatchSize pg. 16

Performanceversant.flushThreshold pg. 17

Generalversant.genericAccess pg. 24

Indexingversant.indexDefine pg. 14

In-memory XML Metadataversant.indexes.xml pg. 23

Indexingversant.indexesDefinitionFile pg. 14

Indexingversant.indexEvolve pg. 14

Indexingversant.inheritIndexes pg. 15

Generalversant.jmx pg. 25

Generalversant.jmxServer pg. 25

Generalversant.jmxServer.password pg. 26

Generalversant.jmxServer.username pg. 25

Performanceversant.level2Cache pg. 17

Generalversant.logJpaExceptions pg. 26

In-memory XML Metadataversant.orm.xml pg. 23

User Authorizationversant.password pg. 9

In-memory XML Metadataversant.persistence.xml pg. 23

Queriesversant.queryBatchSize pg. 18

Queriesversant.queryInterleaveResults pg. 19

Queriesversant.queryTimeZone pg. 20

Automatic Reconnectversant.reconnectCount pg. 10

Automatic Reconnectversant.reconnectListener pg. 10

Automatic Reconnectversant.reconnectWait pg. 11

Schema Handlingversant.schemaDefine pg. 11

Schema Handlingversant.schemaEvolve pg. 12

Schema Handlingversant.schemaLooseMapping pg. 12

Schema Handlingversant.schemaLooseSyncTimeout pg. 13

Connectionsversant.sessionName pg. 8

Indexingversant.skipIndexSynchronization pg. 15

Versant JPA Developer's Guide28

Property Index

CategoryProperty NameGeneralversant.strictXmlValidation pg. 26

Performanceversant.threadPoolSize pg. 18

Generalversant.transactionManagerJndiName pg. 27

Entity Reference Handlingversant.unresolvableReferenceListener pg. 20

Entity Reference Handlingversant.unresolvableReferenceStrategy pg. 21

User Authorizationversant.username pg. 10

Entity Reference Handlingversant.useSoftReferences pg. 21

29Versant JPA Developer's Guide

Property Index

Versant JPA Developer's Guide30

Chapter 2. Naming Conventions

Sections• Entity Names• Entity Attributes

This chapter provides you with information you need to consider when naming metadata in V/JPA.Metadata in this context means class names, field names, property values, database names, usernames, index names, session names, transaction names, etc. Additional considerations for entity(class) names and entity attribute (field) names as they are used by Versant JPA and the VersantJPA Server are also discussed.

General conventions

Metadata names must use the US ASCII 7-bit character set. This is understandable in terms of howand where metadata names are used. Metadata names are used in your Java code and in XML files,for example. And often metadata names must be compatible across different operating systems.

V/JPA does not check that you follow this convention but unpredictable behavior can result if youuse non-ASCII characters in your metadata names.

The ASCII convention for metadata names does not apply to the values used for entity attributessuch as java.lang.String values. Attribute values are stored in the database as UTF-8 encodedstrings.

2.1. Entity NamesVersant JPA uses the entity name associated with your Java class to identify the entity classes inthe database. The entity name, as determined by the following criteria, is the name of the class forall database operations. For example, when performing JPQL queries you specify the entity namein the query predicate.

In V/JPA there are three ways to determine the JPA entity name of a class.

31Versant JPA Developer's Guide

• Use the unqualified name of the class. For example, for the class com.company.datamodel.Book,just the class name without the qualifying package information, Book, is used. This is the globaldefault in V/JPA and follows the JPA specification.

• Use the fully qualified name, including the qualifying package information. For the exampleabove the entity name is com.company.datamodel.Book. You can set this behavior in the persistenceunit with the V/JPA property versant.defaultEntityNames using the valuefullyQualifiedClassName.

• Use the name defined in the @Entity annotation or in the <name> element in the <entity> elementin the mapping file for the persistence unit. Specifying the entity name in this manner takesprecedence. The setting of the versant.defaultEntityNames property will not apply to theseentities.

For example, the following shows setting the entity name of the Book class to Paperback.

package com.company.datamodel;@Entity(name="Paperback")class Book { . . . }

This shows setting the entity name in a mapping file.

<entity class="com.company.datamodel.Book"><name>Paperback</name>. . .

</entity>

Once you have begun using a particular entity naming configuration, you should avoid changingit. Changing the entity names and connecting to an already populated V/JPA database can resultin undesirable behavior. Simply renaming an entity class has the result that entities stored in thedatabase with the previously defined name will not be found using the new name.

Renaming an entity class to a name that is already in use by another class will cause the entitiesof the newly renamed class to be handled as if they are entities of the previously existing class. Ifthe two entity classes have different structures (different fields, field layout) this can result inapplication crashes and/or loss of data. Having two different entity classes sharing a common entityname could occur if, e.g., you are using more than one persistence unit or versions of a persistenceunit and switch between them.

Versant JPA Developer's Guide32

Entity Names

Another potential risk when defining your entity names in multiple persistence units is the sameclass having more than one name. In the database, these will be treated as different entity classesand only the name defined in the persistence unit you use at a given time will be seen.

2.2. Entity AttributesEntity attributes, i.e., field names, follow the general conventions of the Java language. However,Versant JPA imposes the following naming restrictions.

• The name o_ts_timestamp is reserved and not allowed as a user-defined attribute name

• Any name beginning with _vjpa is not allowed

• Names ending in any of the following are not allowed

#null#nulls$keys$values

If any of your V/JPA entity classes contains an attribute with a restricted name, the exceptionReservedAttributeNameException is thrown during enhancement.

33Versant JPA Developer's Guide

Entity Attributes

Versant JPA Developer's Guide34

Chapter 3. Enhancing Your Entity Classes

Sections• The Enhancement Process• Run-time Enhancement• Build-time Enhancement—The Enhancer Ant Task• Build-time Enhancement—The Java Executable Enhancer

In order for Versant JPA Server to properly track modifications of fields and properties in yourpersistent objects, additional functionality must be added to the definitions of your entity classes.For this reason, the byte-code representations of your entity classes (the .class files) need to beenhanced to add the appropriate methods.

With V/JPA this enhancement can be done at run-time using a Java agent or as part of the buildprocess for your application using an ant task or with a Java executable. The following sectionsdescribe the enhancement process and the available enhancement procedures.

3.1. The Enhancement ProcessThe work that the enhancer needs to do is determined by the metadata associated with the classes.This metadata can come from annotations or from a persistence unit (and any mapping filesreferenced by the persistence unit). For example, whether a class is an entity class, or not, may bespecified with the @Entity annotation in your Java source file or by specifying the class as an entityin an ORM file with an <entity> element. At enhancement time, the metadata specified in thepersistence unit has precedence and will override any metadata from annotations.

Resolving the Metadata—Enhancer Modes

For metadata other than annotations, the enhancer needs to know which persistence unit(s) toprocess. There are three modes the enhancer can use in determining the units to process.

single

This is the default mode. The enhancer expects a single persistence.xml file that defines onepersistence unit. The persistence.xml file must be reachable by the class loader. If multiple

35Versant JPA Developer's Guide

files are found or if the file defines more than one persistence unit the enhancer will exit withthe exception CannotResolveSinglePersistenceUnitException.

strict

In this mode you supply a list of persistence unit names to be processed. The persistence.xmlfiles defining the units must be reachable by the class loader.

lenient

This directs the enhancer to scan the class loader for all reachable persistence.xml files andprocess all the persistence units defined in these files.

Metadata Consistency

When you enhance your application classes, the metadata information, whether from annotationsor from a persistence unit, becomes associated with the class files. When you create anEntityManagerFactory V/JPA checks that the information in the class matches the information inthe persistence unit(s). Any conflicts will cause an exception. (Conflicts will not occur if you areusing run-time enhancement.) The following summarizes the possible post-enhancement conflicts.

@Entity

If you have an application class (a non-entity class at enhancement time) and change thepersistence unit after enhancement so that the class is now declared as an entity class, V/JPAwill complainwith an exception.However, an enhanced entity class that is changed to non-entitystatus in the persistence unit will still be an entity class and V/JPA will not complain.

@Id@Transient@Version@Access

Following enhancement, changing the status of a field results in an exception.

Consistency across multiple persistence units

For strict and lenient enhancementmodes the consistency of themetadata in the various persistenceunits is also important. If information about an entity class is found in more than one of theprocessed persistence units the informationmust agree. This applies to both run-time andbuild-time

Versant JPA Developer's Guide36

The Enhancement Process

enhancement. Conflicts will result in V/JPA throwing an exception when processing the metadata.The following must be in agreement.

Entity level

• Access type (field vs. property)

• Attribute list

Attribute level

• Access type (field vs. property)

• ID metadata

• Version metadata

• Transient metadata

3.2. Run-time EnhancementThe entity class enhancement is done at run-time through a Java agent. That is, the enhancer runsin the JVM and the run-time entity class definitions are enhanced when a class is loaded for use inyour application. Only those classes listed in the persistence unit (persistence.xml file) areenhanced.

To perform run-time enhancement, whenever you run your V/JPA application you must start theJVM with a -javaagent option specifying the versantjpa-2.0.jar file as the agent. For example,for a typical Windows installation the argument is as follows (single enhancement mode).

-javaagent:C:\Versant\vjpa2\lib\versantjpa-2.0.jar

For strict enhancement, specify the persistence unit(s) as follows.

-javaagent:C:\Versant\vjpa2\lib\versantjpa-2.0.jar=Unit-1,Unit-2,Unit-n

For lenient enhancement, specify the -lenient option as follows.

-javaagent:C:\Versant\vjpa2\lib\versantjpa-2.0.jar=-lenient

37Versant JPA Developer's Guide

Run-time Enhancement

The versantjpa-2.0.jar is provided by the Versant JPA plugin. It is also available for standaloneuse in the lib directory in your V/JPA installation. Adjust the path accordingly for your javacommand line calls.

Run-time enhancement with the V/JPA Eclipse plug-in

If you are using the Versant JPA Eclipse plugin, this argument can be automatically included intoeach of your run configurations. The project needs to have the JPA Nature configured. To enablethis nature for a Java project, right click on the project name in the Package Explorer tree and chooseVersant JPA Nature > Add JPA Nature. You can remove the nature from any project through the same contextmenu.

3.3. Build-time Enhancement—The Enhancer Ant TaskAn ant task is provided for enhancing your V/JPA .class files as part of the application build process.The task class is com.versant.jpa.enhancer.ant.EnhancerTask and is contained in theversantjpa-2.0.jar file. The task will enhance all .class and .jar files that are contained in thespecified ant <fileset> collection.

By default, only the classes listed in the persistence units are enhanced. You can direct the enhancerto enhance all classes that are annotated as @Entity, even if the class is not specified in a persistenceunit, by setting the task attribute enhanceUnlistedEntities value to true.

Using the Enhancer Task

To use the task within an ant build file, declare the task as follows (you can use any name you wishfor the task name).

<taskdef name="VJPAEnhancer"classname="com.versant.jpa.enhancer.ant.EnhancerTask"classpath="versantjpa-2.0.jar" />

Call the task after you have compiled your V/JPA application classes. The task copies the files youspecify in a <fileset> element to the given destination directory and enhances the entity classes(.class or .jar files) in the destination. The basic syntax for single-mode enhancement is as follows.

Versant JPA Developer's Guide38

Build-time Enhancement—The Enhancer Ant Task

<VJPAEnhancer destdir="resultPath"><fileset>...</fileset>

</VJPAEnhancer>

Optionally you can define or reference a classpath with the classpath, classpathref andinheritsClasspath attributes. For specifying strict or lenient enhancementmode use the attributepersistenceUnit or lenient, respectively. (Attributes are described below.)

The following example call will copy all files in sourcePath/bin to resultPath/bin and enhancethe entity classes defined in any .class and .jar files. A classpath is also specified. The enhancedversions are found in the location resultPath/bin.

<VJPAEnhancer destdir="resultPath/bin" classpath="sourcePath/META-INF"<fileset dir="sourcePath/bin">

<include name="**/*" /></fileset>

</VJPAEnhancer>

For .jar files, the enhancer creates a new .jar file in the result (destdir) directory with the samename and structure, enhancing or copying the content as appropriate.

In-place enhancing

You can also use the ant enhancer task to enhance .class files in-place by setting the destdir tothe same directory specified for the <fileset>. In-place enhancement will not enhance .jar filecontents.

Table 3.1. V/JPA Enhancer ant Task Attributes & Elements

DescriptionAttributeSpecifies the destination directory. All files specified in the<fileset> are copied here. Any .class and .jar (not in-place)files are enhanced in this location.

destdir

Required

Specifies a classpath, as an ant path structure, to resolvedependencies and/or resources needed during enhancement, e.g.,persistence.xml.

classpath

Optional

39Versant JPA Developer's Guide

Build-time Enhancement—The Enhancer Ant Task

DescriptionAttributeAllows you to reference a pre-defined ant path as the classpathfor the enhancement task.

<path id="myref"><fileset>...</fileset>

classpathref

<path location="..." /></path><VJPAEnhancer ... classpathref="myref">

...</VJPAEnhancer>

Optional

Determines whether classes that are annotated as entity classeswith the @Entity annotation but not listed in a persistence unit

enhanceUnlistedEntities

will be enhanced. The default is that unlisted classes are notenhanced. To enhance all classes with the @Entity annotation,whether listed in a persistence unit or not, set the value of thisattribute to true.

Optional, default is false

Determines whether the enhancer uses the inherited JVMclasspath. Note that if set to false even basic Java classes will

inheritsClasspath

not be found unless you have specified the necessary locationswith the classpath or classpathref attributes.

Optional, default is true

Specifies a comma-separated list of persistence units, by name,for strict-mode enhancement.

<VJPAEnhancer destdir="resultPath"persistenceUnit="Unit-1,Unit-2,Unit-n">

persistenceUnit

<fileset>...</fileset></VJPAEnhancer>

Versant JPA Developer's Guide40

Build-time Enhancement—The Enhancer Ant Task

DescriptionAttributeSpecifies lenient enhancement mode when set to true

<VJPAEnhancer destdir="resultPath"lenient="true">

lenient

<fileset>...</fileset></VJPAEnhancer>

ElementSpecifies the files to be enhanced. All files specified are copiedto the destdir location. Any .class and .jar files (.jar files arenot enhanced in-place) are enhanced (in the destdir location).

<fileset>

Required

3.4. Build-time Enhancement—The Java Executable EnhancerAn executable class, com.versant.jpa.enhancer.main.EnhancerMain, is also provided, in theversantjpa-2.0.jar file, for performing the enhancement step. The basic syntax for EnhancerMainis as follows.

EnhancerMain [-i] -cp <dependencies> -d <destdir> -b <basedir>[<file> [ ... <fileN>]]

(The arguments are described below.)

By default, only the classes listed in the persistence units are enhanced. You can direct the enhancerto enhance all classes that are annotated as @Entity, even if the class is not specified in a persistenceunit, by using the -eu/--enhanceUnlistedEntities argument.

The following example call will enhance all entity classes in the bin folder and save the enhancedversions to the enhanced-bin folder.

java-cp %VJPA_LIB_DIR%/versantjpa-2.0.jar;

%VJPA_LIB_DIR%/commons-cli-1.2.jar;%VJPA_LIB_DIR%/antlr-runtime-3.5.jar;

41Versant JPA Developer's Guide

Build-time Enhancement—The Java ExecutableEnhancer

%VJPA_LIB_DIR%/asm-all-4.1.jar;%VJPA_LIB_DIR%/jta-1.1.jar;%VJPA_LIB_DIR%/javax.persistence_2.0.0.jar;%VJPA_LIB_DIR%/slf4j-api-1.7.2.jar

com.versant.jpa.enhancer.main.EnhancerMain -cp bin -b bin -d enhanced-bin

(This assumes that you have set the value of VJPA_LIB_DIR to the location of the lib directorywhereyou installed Versant JPA.)

The example above uses single enhancementmode (the default). For strict or lenient enhancementmode, set the appropriate argument, -u/--persistenceUnit or -l/--lenient, respectively.

The following table describes the EnhancerMain arguments.

Table 3.2. V/JPA Enhancer Class EnhancerMain Arguments

DescriptionArgumentSpecifies isolated mode, i.e., the classpath will not be inheritedfrom the JVM in which the enhancer is running.

-i

This is optional. By default, classes from the enhancer JVM willbe used to resolve dependencies in the classes being enhanced.

Used to resolve dependencies such as, e.g., the persistence unitfile, persistence.xml

-classpath-cp

This is optional.

Specifies the base directory containg the files to enhance.-b

This is optional. The default is the current directory.

Specifies the destination directory. The files to be enhanced arecopied to this directory and enhanced, as appropriate.

-d

This is required.

In-place enhancement

You can perform the enhancement for .class files in-place byspecifying the same directory for the destination as for the basedirectory. In-place enhancement applies only for .class files andwill not enhance .jar file contents.

Versant JPA Developer's Guide42

Build-time Enhancement—The Java ExecutableEnhancer

DescriptionArgumentDetermines whether classes that are annotated as entity classeswith the @Entity annotation but not listed in a persistence unit

-eu--enhanceUnlistedEntities

will be enhanced. The default is that unlisted classes are notenhanced. Use this argument to enhance all classes with the@Entity annotation, whether listed in a persistence unit or not.

This is optional.

Prints a help screen and exits-h

A .class or a .jar file. (Wildcards are not supported.)<file>

Optional. If no files are specified, all the files in the base directory(specified by the -b argument) are recursively enhanced.

Specifies a comma-separated list of persistence unit(s) for strictenhancement mode.

java -cp versantjpa-2.0.jar EnhancerMain \-d destinationDirectory -u Unit-1,Unit-2,Unit-n

-u--persistenceUnit

Specifies lenient-mode enhancement.

java -cp versantjpa-2.0.jar EnhancerMain \-d destinationDirectory -l

-l--lenient

43Versant JPA Developer's Guide

Build-time Enhancement—The Java ExecutableEnhancer

Versant JPA Developer's Guide44

Chapter 4. Versant JPA Server Administration API

The Versant JPA Server administration API is located in the package com.versant.admin. It allowsto you create and remove Versant JPA Server databases from within your application code. Thepackage consists, primarily, of the ServerAdministration class. Use one of the methodsServerAdministration.createDatabase(..) to create a new database,ServerAdministration.verifyDatabaseExists(..) to check whether a database exists andServerAdministration.removeDatabase(..) to remove an existing database.

The administration API class and methods are described in the Javadoc reference(vjpa2/doc/javadoc/index.html, class ServerAdministration). You can also see how the V/JPAadministation API is used to perform these server operations inmany of the V/JPA examples. Refer,for example, to the tutorial application class Utility_createTutorialDatabase.

45Versant JPA Developer's Guide

Versant JPA Developer's Guide46

Chapter 5. Distributed Databases

Versant JPA supports working with distributed databases, that is, the ability to store objects to andretrieve objects from multiple databases within the context of a single EntityManagerFactory.

Using the Generic API

If you will be using the generic API with distibuted databases, refer to Section 21, “The Generic APIand Distributed Databases” pg. 153.

The databases to use are specified as a list of database URLs in the value of theversant.connectionURL property. Each URL is separated by the | character. For example, thefollowing lists two databases.

<property name="versant.connectionURL"value="versant:database1@localhost|versant:database2@myOtherMachine"/>

The first database in the list becomes the default database. This default database is where newobjects are persisted when a database is not otherwise specified. The role of the default databaseis described in detail below. The default database can be changed within your application by settingthe entity manager property VersantEntityManager.setDefaultDatabase(Database). Use theunwrap()method provided by the EntityManager interface, i.e.,EntityManager.unwrap(VersantEntityManager.class), to get the VersantEntityManager instance.

Note that the list of databases for an EntityManagerFactory instance can not be changed at runtime,but it is possible to create another instance of EntityManagerFactorywith a different set of databases.The list of databases for a particular VersantEntityManagerFactory can be obtained viagetAllDatabases(). Also, the method getDatabase() of VersantEntityManager can be used to findout the database for a given persistent object.

Atomic Commit

The default database at the time the transaction is started (when em.getTransaction().begin() iscalled) becomes the coordinator database of this transaction. If objects in any database other thanthe coordinator database are modified within a transaction, then at transaction commit time, the2-phase commit protocol is used. The 2-phase commit guarantees an atomic commit. However, a2-phase commit is more expensive (slower) than a simple commit, because it requires more

47Versant JPA Developer's Guide

communication and logging operations.Whenobjects in only the coordinator database aremodified,then a less expensive simple commit is executed.

The Default Database and Persistent Objects

When using distributed databases, if a database is not specified, objects that are madepersistent—either implicitly, via cascading the persist operation, or explicitlywith a persist(object)API call—are stored in the current default database. The default database is the first in the list ofdatabases given for the versant.connectionURL persistence unit property or the database you specifywith the VersantEntityManager.setDefaultDatabase() entity manager property.

You can override the default by specifying the database where you want the objects to be storedwhen calling the persist()method. Themethod to specify a database is persist(database,object).If the database is specified, all objects that are implicitlymade persistent, i.e., via cascading thepersist operation, during the make persistent operation will also be stored in the specified database.

A few exampleswill helpmake this clear. The first example stores the objects in the default database.Assume that at the beginning of the examples, the default database is dbOne.

em.getTransaction().begin();// default database is dbOne

Person p = new Person();// Person is a persistence capable class

em.persist(p);// will be assigned to dbOne (the default) at commit

p.getAddresses().add(new Address());// Address is a persistence capable class

em.getTransaction().commit();

Here the default database, dbOne, is used for both objects in the object network. The Person objectbecause a different database was not specified and the Address object via cascading the persistoperation. The asssignment is made when the transaction commits.

The next example will store the same object network. However, the objects in the network willreside in different databases.

em.getTransaction().begin();// default database is dbOne

Person p = new Person();em.persist(dbTwo, p);

Versant JPA Developer's Guide48

// the new Person object is assigned to dbTwop.getAddresses().add(new Address());

// the new Address object will be assigned to dbOneem.getTransaction().commit();

When em.persist(dbTwo, p) is called, the Address object is not yet a part of the object network.Once the persist() call finishes, the default database is again used. So, it is dbOne that is assignedto the address when it ismade persistent, via cascading the persist operation from the Person object,during the commit operation.

Here is another example that stores both objects of the object network in the same database, butnot the default database.

em.getTransaction().begin();// default database is dbOne

Person p = new Person();p.getAddresses().add(new Address());

// the new Address object is not yet assigned to a databaseem.persist(dbTwo, p);

// the new Person and Address objects will be assigned to dbTwoem.getTransaction().commit();

Since the Address object was a part of the object network when the Person object is assigned todbTwo, it is assigned to the same database. The point of this and the previous example is that theorder of the calls can make a difference for a distributed database system.

Finally, here is an example using setDefaultDatabase().

em.getTransaction().begin();// default database is dbOne

em.setDefaultDatabase(dbTwo);// change the default database for this pm

Person p = new Person();em.persist(p);

// the new Person object is assigned to dbTwop.getAddresses().add(new Address());

// the new Address object will also be assigned to dbTwoem.getTransaction().commit();

49Versant JPA Developer's Guide

Note that calling persist() for an object which has already been written to a database (in a priortransaction or a flush operation) has no effect and will not change the database assignment for theobject.

A new object that has been made persistent in the current transaction cannot have its assigneddatabase changed. If this is attempted an exception will be thrown. This applies to cascadingpersistence as well. For example, if you need to persist a tree-like structure, where the root nodeshould be in one database but its children in a different database (or different databases), eitherpersist the children first to the desired database(s) and the root node afterwards or set the referencesto the children after persisting the root node.

Queries

The following apply when querying multiple databases.

• By default, queries are executed on all databases. You can limit the number of database queriesexecuted by setting the property VersantEntityManager.setDefaultQueryDatabases(Database[]).

Alternatively, you can use the overload for getResultList(Database[]), provided in theVersantQuery class, which allows the explicit specification of a set of databases on which thequery needs to be executed.

• Expressions in the filter clause (i.e., the WHERE part), are not evaluated across multiple databasesbut only within each database.

• For ORDER BY queries on multiple databases, the result order may differ from the result from asingle database. For multiple databases, the result order is determined by the standard Javacomparison for the type. For a single database, the ordering will be determined by the orderingused in the server.

Merging with Distributed Databases

When youmerge a detached entity (and its associated network) to an entity manager withmultipledatabases, any entities that already exist in a database will be returned to that database. Newentities will be created in the currently defined default database (refer to Section 5, “The DefaultDatabase and Persistent Objects” pg. 48). V/JPA provides two additional overloads of theEntityManager.merge()method in VersantEntityManager to allow you to specify the database fornew entities during the merge operation (refer to the V/JPA API reference).

Versant JPA Developer's Guide50

Chapter 6. Second-level Cache

Sections• Configuration• Pluggable Cache

- Ehcache- Infinispan

The JPA specification supports the use of a second-level cache. The specification defines thesyntax—persistence unit elements, annotations, interface API—to control how the entities in yourapplication will interact with the cache. The actual implementation of the cache is left to thepersistence provider. Versant JPA provides a pluggable cachemechanism that allows you to use athird-party cache implementation.

Caching in the JPA specification

The Versant JPA cache implementation follows the JPA specification given in JSR 317: Java™Persistence API, Version 2.0, section 3.7. To learn about using a second-level cache with your V/JPAapplication, refer to this section of the specification, or other sources for JPA information, in additionto the V/JPA-specific information discussed here.

6.1. ConfigurationTo enable the second-level cache, you specify the <shared-cache-mode> element in the persistenceunit (the persistence.xml file) for the application. The <shared-cache-mode> element has thefollowing possible values.

ALLNONEENABLE_SELECTIVEDISABLE_SELECTIVEUNSPECIFIED

The values ALL and NONE enable caching for all entities or disable caching, respectively. The valuesENABLE_SELECTIVE and DISABLE_SELECTIVE determine how the Cacheable annotation is handled.This annotation is used to fine-tune whether a particular entity is cached when caching is enabled

51Versant JPA Developer's Guide

by either of these values for the <shared-cache-mode> persistence unit element. (The preceedingis in line with the JPA specification. Refer to specification section 3.7.1 for detailed information.)

Persistence-provider (V/JPA) implementations

In Versant JPA, the <shared-cache-mode> value UNSPECIFIED is interpreted as DISABLE_SELECTIVEand has the same meaning.

Additionally, V/JPA handles the value CacheStoreMode.USE for the cache store mode in the sameway as CacheStoreMode.REFRESH. (Refer to section 3.7.2 of the JPA specification for more detail.)

6.2. Pluggable CacheVersant JPA provides pluggable support for second-level caching. By default, no second-level cacheis active. A cache binding is provided through an implementation class. The specific cacheimplementation used is configured in the persistence.xml file with the versant.level2Cacheproperty.

If, for any reason, the cache instantiation fails during EntityManagerFactory startup, V/JPA willabort the startup process and propagate the causing exception.

V/JPA provides support for the Ehcache and Infinispan cache implementations. These are describedin the following sections.

6.2.1. Ehcache

Versant JPA comes bundled with support for Ehcache in local, distributed and replicated modes.(You can get information about Ehcache at ehcache.org.)

Prerequisites

The following is required to use Ehcache with V/JPA.

• Ehcache version 2.6.2 or higher (tested against ehcache-2.6.2-distribution.tar.gz)

Versant JPA Developer's Guide52

Pluggable Cache

• The ehcache-core-2.6.2.jar file must be in the classpath. Depending on the runmode you haveconfigured for Ehcache, you may need additional .jar files from the Ehcache distribution whichcontain the bindings for JGroups, Terracotta, etc.

Factory Implementation

The V/JPA Ehcache factory implementation iscom.versant.jpa.cache.provider.ehcache.EhcacheFactory. This is the class passed to theversant.level2Cache property.

Here is an example versant.level2Cache persistence unit entry for Ehcache.

<property name="versant.level2Cache" value="com.versant.jpa.cache.provider.ehcache.EhcacheFactory:name=Cache1;configFile=ehcache.xml" />

In the property value is the factory name (fully qualified). Any factory properties follow the factoryname. They are separated from the name by a colon and are provided in a semicolon-separated list.

The following factory properties are used with EhcacheFactory.

configFile

The name of the Ehcache configuration file. The file must be in the classpath. For informationregarding the Ehcache configuration file, refer to the Ehcache documentation.

(required)

allowed values:

a valid file name

default:

none

name

A name for the cache. The Ehcache configuration file must define a cache that matches thisname.

(required)

allowed values:

53Versant JPA Developer's Guide

Pluggable Cache

string

default:

none

registerJMX

If true, the Ehcachemanager instance registers itself for JMX monitoring.

(optional)

allowed values:

true, false

default:

true

6.2.2. Infinispan

Versant JPA comes bundled with support for Infinispan in local and distributed modes. (You canget information about Infinispan at www.jboss.org/infinispan.)

Prerequisites

The following is required to use Infinispan with V/JPA.

• Infinispan version 5.2.6 or higher (V/JPA testing performed using infinispan fromjboss-eap-6.2.0.zip distribution)

• In a minimum configuration, the following files must be in the classpath.

infinispan-core-5.2.7.Final-redhat-1.jarjboss-logging-3.1.2.GA-redhat-1.jarjboss-marshalling-1.3.18.GA-redhat-1.jarjboss-marshalling-river.1.3.18.GA-redhat-1.jarstaxmapper-1.1.0.Final-redhat-2.jarjgroups-3.2.12.Final-redhat-2.jarrhq-pluginAnnotations-3.0.4.jar

Versant JPA Developer's Guide54

Pluggable Cache

Depending on the run mode you have configured for Infinispan, you may need additional .jarfiles from the Infinispan distribution which contain the bindings for JGroups, etc.

Using Infinispan in JBoss AS

The recommended configuration for Infinispan inside JBoss EAP is not to deploy Infinispan alongwith the V/JPA module or with your application, but use the builtin Infinispan module instead.

• In the V/JPA module.xml, add a dependency to the Infinispan module.

<module name="org.infinispan" />

• In your application manifest file, MANIFEST.MF, declare a dependency to the Infinispan module.

Dependencies: org.infinispan

Factory Implementation

The V/JPA Infinispan factory implementation iscom.versant.jpa.cache.provider.infinispan.InfinispanCacheFactory. This is the class passedto the versant.level2Cache property.

Here is an example versant.level2Cache persistence unit entry for Infinispan.

<property name="versant.level2Cache"value="com.versant.jpa.cache.provider.infinispan.InfinispanCacheFactory:name=Cache1;configFile=infinispan.xml" />

The property value is the factory name (fully qualified). Any factory properties are specified in asemicolon-separated list following the factory name. The property list is separated from the nameby a colon. (The value line, above, is split to fit the page. In practice, keep the line together.)

The following factory properties are used with InfinispanCacheFactory.

configFile

The name of the Infinispan configuration file. The filemust be in the classpath. For informationregarding the Infinispan configuration file, refer to the Infinispan documentation.

55Versant JPA Developer's Guide

Pluggable Cache

(required)

allowed values:

a valid file name

default:

none

name

A name for the cache as declared in the Infinispan configuration file.

(required)

allowed values:

string

default:

none

JGroups using UDP

If you are using Infinispan with a JGroups configuration that uses UDP for the transport protocol,you may experience problems such as random lockups, network errors or misbehaving caches onmachines with IPv6 enabled. To prevent these issues, add the JVM parameter-Djava.net.preferIPv4Stack=true or configure Infinispan to use JGroups with TCP rather thanUDP.

Versant JPA Developer's Guide56

Pluggable Cache

Chapter 7. Automatic Flushing

Occasionally, you may have the need for large transactions containing entities numbering in thethousands, hundreds of thousands or evenmore. This can be the casewhen importing large amountsof data, for example. While not a problem in themselves, such large transactions can exceed theavailablememory. Anticipating these cases could require you tomodify your application. However,Versant JPA provides an automatic flushingmechanism that allows your application to handle suchlarge transactions without any modifications to your code. V/JPA will automtically perform a flushoperation at regular intervals based on the flush threshold, that is, when a given number ofmodifiedobjects in the transaction is reached. Once flushed, the local garbage collector can remove thein-memory instances. By default, this interval is 10000 but you can change that number (or evendisable automatic flushing) with the flushThreshold property.

Normally, automatic flushing will be invisible to your application but could lead to unexpectedbehavior without an understanding behind its operation. As persistent entity instances aremodifiedin a transaction, they are marked to be written to the database in the transaction commit phase.With automatic flushing, when the number ofmodified entities reaches the flush threshold, a flushoperation is triggered and the modified entities are written to the database. Flushing of modifiedentities then occurs at regular intervals. However, entities so written are not yet committed andyour application can still perform a rollback if needed. Since entities that are automatically flushedare still associated with the active transaction, theymaintain their lock status until the transactionends (commit or rollback).

Refer also to Section 23.5, “Flush Operations” pg. 163

57Versant JPA Developer's Guide

Versant JPA Developer's Guide58

Chapter 8. Using an Application Server

Sections• Setting up JBoss• JBoss Applications• Transaction Manager Discovery• XA Transactions with JBoss• Restrictions

This section briefly describes how to set up V/JPA for use with the JBoss application server.

8.1. Setting up JBossV/JPA will need to be configured as a JBoss module. Perform the following steps.

• In the modulesdirectory of your JBoss installation, create a directory named com/versant/jpa/main.Copy the following JAR files from your V/JPA lib directory to the new JBoss module directory.

versantjpa-2.0.jarversantjpa-jboss-recovery-2.0.jarantlr-runtime-3.5.jarasm-all-4.1.jar

• Create a module.xml file in the directory with the following contents.

<?xml version="1.0" encoding="UTF-8"?><module xmlns="urn:jboss:module:1.0" name="com.versant.jpa">

<resources><resource-root path="versantjpa-2.0.jar"/><resource-root path="versantjpa-jboss-recovery-2.0.jar"/><resource-root path="antlr-runtime-3.5.jar"/><resource-root path="asm-all-5.0.3.jar"/>

</resources>

<dependencies><module name="javax.api"/>

59Versant JPA Developer's Guide

<module name="javax.persistence.api"/><module name="javax.transaction.api"/><module name="org.jboss.dmr"/><module name="org.jboss.msc"/><module name="org.jboss.staxmapper"/><module name="org.jboss.as.controller"/><module name="org.jboss.as.naming"/><module name="org.jboss.as.transactions"/><module name="org.jboss.jboss-transaction-spi"/><module name="org.jboss.jts"/><module name="org.jboss.jts.integration"/><module name="org.jboss.logging"/><module name="org.slf4j"/>

</dependencies></module>

• Add the V/JPA module as an extension to the JBoss configuration file (standalone.xml).

<?xml version='1.0' encoding='UTF-8'?><server xmlns="urn:jboss:domain:1.4">

<extensions>. . .<extension module="com.versant.jpa"/>

</extensions><management>

. . .</management><profile>

. . .</profile>. . .

</server>

8.2. JBoss ApplicationsOnce you haveV/JPA configured as a JBossmodule, you can access its JPA provider from applicationsrunning in JBoss by configuring the persistence unit as follows.

Versant JPA Developer's Guide60

JBoss Applications

<persistence-unit name="vjpa_jboss_example" transaction-type="JTA"><provider>com.versant.jpa.core.VersantPersistence</provider>. . .<properties>

<property name = "jboss.as.jpa.providerModule" value="com.versant.jpa" />. . .

</properties></persistence-unit>. . .

8.3. Transaction Manager DiscoveryThe default transaction manager is found by JNDI lookup. The following JNDI names are tried.

(JBoss)java:/TransactionManager(GlassFish)java:appserver/TransactionManager(Resin 3.x)java:comp/TransactionManager(Borland Enterprise Server / Sun AppServer)java:pm/TransactionManager

To override the default lookup name, you can specify the propertyversant.transactionManagerJndiName in the persistence unit (persistence.xml file).

8.4. XA Transactions with JBossThe Transaction Manager component of JBoss is JBossTS (formerly known as Arjuna TransactionService). Unfortunately, the JTA specification specifies no portableway to hook-upwith the recoverymodule of a Transaction Manager. Therefore, specifically for JBoss, we provide a recovery modulewhich needs to be set-up in your deployment. Without this recovery module, JBoss is not able torecover prepared transactions.

Configuring the recovery resource

V/JPA provides a separate XAResource for recovery only. This XAResource is registered with JBossto allow the JBoss Transaction Manager, JBossTS, to call this resource for recovering prepared, butnot yet committed transactions. JBossTS calls this recovery resource periodically to look fortransactions which should be recovered. If the database is unavailable at the point when it is called

61Versant JPA Developer's Guide

Transaction Manager Discovery

the recovery resource throws an XAExceptionwith the error codeXAER_RMFAIL. This causes JBossTSto log thewarningmessage ARJUNA016037: Could not find new XAResource to use for recoveringnon-serializable. This is not an issue, and simply indicates that the resource is currently notavailable. As soon the database is up again the recovery resource finds transactions which shouldbe recovered, if there are any, and no further warning messages are logged.

Add the V/JPA recovery resource as a profile subsystem to the JBoss configuration file(standalone.xml).

<?xml version='1.0' encoding='UTF-8'?><server xmlns="urn:jboss:domain:1.4">

. . .<profile>

<subsystem xmlns="urn:versant:jpa:xarecovery:2.0"/>. . .

</profile>. . .

</server>

Configuring transaction timeout

The V/JPA server supports a transaction timeout for XA transaction branches. Not-yet-preparedtransaction brancheswill be rolled back unilaterally by V/JPA after the timeout. (Refer to Section 9.3,“XADistributed Transactions” pg. 68.) The timeout is configured in standalone.xml in a <subsystem>section as shown.

<subsystem xmlns="urn:jboss:domain:transactions:1.4"><core-environment>

<process-id><uuid/>

</process-id></core-environment><recovery-environment socket-binding="txn-recovery-environment"

status-socket-binding="txn-status-manager"/><coordinator-environment default-timeout="300"/>

</subsystem>

Versant JPA Developer's Guide62

XA Transactions with JBoss

Logging

Refer to Section 19.1.1, “XA Resource Logging” pg. 130 for information about enabling logging forthe XA resources.

8.5. Restrictions• Supported versions

Currently (V/JPA 2.0.17), only JBoss EAP 6.2.0 is supported.

• Java class enhancement

Versant JPA runtime enhancement does not work with JBoss EAP 6.2.0—use build-timeenhancement. Refer to Chapter 3, Enhancing Your Entity Classes pg. 35 for information aboutV/JPA enhancement. (This restriction is the result of a JBoss bug which is fixed in JBoss version7.2-Alpha2.)

• XAResource.isSameRM() implementation

The V/JPA implementation of the XAResourcemethod isSameRM() always returns false. Refer toSection 23.15, “XAResource Implementation” pg. 170.

63Versant JPA Developer's Guide

Restrictions

Versant JPA Developer's Guide64

Chapter 9. Transactions

Sections• Resource-local Native Transactions• Distributed Native Transactions• XA Distributed Transactions• Identifying Dead Transactions

A transaction is a single logical operation on a set of data in a database. V/JPA supports ACIDtransactions. ACID is an acronym for Atomicity, Consistency, Isolation, Durability. This sectiondiscusses theV/JPA support for recovery to handle failed transactions and to guarantee the atomicityof ACID.

V/JPA classifies transactions based on the following types.

• Resource-local native transactions involving only a single database

• Distributed native transactions involvingmultiple databases andmaking use of theV/JPA-specific2-Phase-Commit (2PC) protocol

• XA distributed transactions managed by an external transaction manager that adheres to theXA/Open standard and typically involving multiple databases and/or other resources that needto participate in the 2PC protocol

StandaloneV/JPA applications typically use native transaction support, resource-local or distributed.Applications in managed environments such as JBoss will typically use XA transaction support.

The following sections describe the behavior of these different transaction classifications and howthey interact with various system components.

9.1. Resource-local Native TransactionsOnly a single database participates in this type of transaction and it is always the client applicationthat begins the transaction. The transaction ends when the client invokes commit() or rollback()as appropriate.

65Versant JPA Developer's Guide

Certain circumstances can effect the proper completion of the transaction. You should be awareof the following behaviors of resource-local native transactions.

Rollback on error

The Versant JPA Server may not be able to reliably complete the client commit as a result of certainerror conditions. For example, a timestamp validation for amodified objectmight fail. In such caseswhere an error occurs, the Versant JPA Server will rollback the transaction and signal the clientwhich will throw an exception.

Abnormal disconnect

If the client disconnects abnormally from theV/JPA server before ending the transaction, the serverwill eventually detect this situation and unilaterally rolls back the transaction. If the serverterminates abnormally, it will rollback unfinished transactions once the database is restarted andperforms recovery. The recovery logic is executed by the V/JPA server and undoes all changes thetransaction might have done so far to permanent structures in the database.

If the client does not end the transaction (by issuing a commit() or rollback() call) the transactionstays active for an arbitrary amount of time until either the client is disconnected or the server isshutdown.

9.2. Distributed Native TransactionsWhen multiple databases participate in a native transaction, the 2-Phase-Commit (2PC) protocolis used to commit a transaction. Typically, there are two roles in such a protocol, the transactionmanager (or coordinator) and participant. There is a single transaction manager, but there may bemultiple participants. The part of a transaction associated with a participant is called a transactionbranch.

For efficiency, in the V/JPA implementation there is no separate transaction manager componentwith its separate transaction log. Rather, the transaction manager logic is folded into the clientlibrary, along with merging the log entries for the overall transaction with that of one particularparticipant. In V/JPA the database containing this merged log is called the coordinator databasewhile all the the other databases are called participant databases.

The coordinator database

In V/JPA the default database determines the coordinator database. Since the application can directwhich is the default database, the coordinator might be different for the same set of databases,

Versant JPA Developer's Guide66

Distributed Native Transactions

even within a given entity manager factory, or—for subsequent transactions—even for the sameentity manager. Refer to Chapter 5, Distributed Databases pg. 47.

The commit() call issued by the client is executed in two phases, a voting/prepare phase and acommit/completion phase. (If the client calls rollback(), the transaction is simply rolled back onall databases as if the distributed transaction were individual resource-local transactions.)

The client logs the beginning of the commit() in the coordinator log file and then calls prepare onall participants. If all participants vote to commit, this decision ismade permanent in the coordinatorlog file and all participants are told to actually commit. If any participant votes to rollback, thecoordinator instructs all participants to rollback, even those participants who voted to commit.The transaction is considered to be committed (or rolled back) as soon as the coordinator log recordwith the voting decision is written and flushed to the disk.

Any error will occur either before or after the transaction outcome has been decided by thecoordinator. If the error occurs before that decision, a transaction branch can unilaterally be rolledback by the V/JPA server when it performs recovery, e.g., after a database restart or detection of alost client connection. The responsibility for recovering not-yet-prepared transactions is with theV/JPA server.

If the error happens after that decision, then some transaction branches might be in doubt aboutthe transaction outcome. The recovery logic for that case is part of the client library. To be able torecover one particular transaction branch, the client needs to be able to talk to the coordinatordatabase and the respective participant database(s). As long as the communication is inhibited,the transaction branch is not recovered. There is no heuristical completion implemented by theVersant JPA Server. This means the responsibility to recover prepared transaction branches (whichcan be either commit or rollback, depending on the logged transaction outcome), is with the V/JPAclient. If the client cannot roll back or commit the transaction, the transaction state is kept by theV/JPA Server. Refer to Section 9.4, “Identifying Dead Transactions” pg. 68.

1-phase commit optimization

If a transaction consists of only a single branch or if only one branch contains modified objects,the commit procedure can be optimized to the equivalent of a resource-local commit. This so-called1-phase commit optimization is supported by V/JPA provided that the single participant is thecoordinator database. To use this optimization you can determine the coordinator before beginningthe transaction by setting the default database for your list of distributed databases. As mentionedin the note above, the default database acts as the coordinator database for distributed tranasctions.Refer to Chapter 5, Distributed Databases pg. 47 for information about how to set the default database.

67Versant JPA Developer's Guide

Distributed Native Transactions

9.3. XA Distributed TransactionsThe X/Open XA specification is a standard defining an interface for resources participating in anexternallymanaged distributed transaction. The standard ismapped to Java specifically by the JavaTransaction API (JTA) specification.

With XA there is a separate software component called the Transaction Manager. The TransactionManager contains the logic to drive the 2-Phase Commit (2PC) protocol. It controls the transactionactivities for all participants. For example, the manager may maintain its own separate log file torecord the transaction outcome decisions, etc. Each participant in such a distributed transactionis represented as an XAResource. However, this is transparent to the application developer, as theexternal interface to the transaction is with the Transaction Manager API. This API can be usedmanually (e.g., JTA) or automatically by using containermanaged transactions inside an applicationserver.

The Transaction Manager is responsible for recovering all prepared transaction branches in thecase of an error. The behavior is different for not-yet-prepared transaction branches. As with nativedistributed transactions, if such branches are detected by the V/JPA server during recovery of adatabase restart, they are simply rolled back. However, unlike with native distributed transactions,the V/JPA server is usually not capable of detecting a client failure during normal operation due tothe fact that an XA transaction branch is not strongly coupled to a physical connection from clientto server. To overcome this problem, the V/JPA server supports a transaction timeout for XAtransaction branches. A not-yet-prepared transaction branch will be rolled back unilaterally byV/JPA if the timeout event occurs.

Refer to Section 8.4, “XA Transactions with JBoss” pg. 61 for information on configuring V/JPA XAsupport for JBoss.

Limitations

• Aswith native distributed transactions, the V/JPA server does not support heuristical completionof transaction branches.

9.4. Identifying Dead TransactionsYou can use the dbtool command line utility to identify dead transactions. A transaction is reportedas dead if the process which started the transaction is no longer connected to the database server.In the case of XA transactions, the transaction manager might still be able to complete thetransaction since the transaction can move between processes.

Versant JPA Developer's Guide68

XA Distributed Transactions

The basic command call is dbtool -nosession -trans -info DatabaseName. Following are someexample calls.

C:\Windows\system32>dbtool -nosession -trans -info jpadb1VERSANT Utility DBTOOL Version 8.0.3Copyright (c) 1988-2014 VERSANT Corporation

** Short transaction Info **

-----------------------------------------------------------------------------------------Tx ID Coord count flags server[pid.tid] client[pid name] session-name long trans ID----------------------------------------------------------------------------------------2976.0.226352 y 00001 x0290 00980.01768 03880 user V/JPA

The flags x0290 indicate that this is a simple, resource-local native transaction and is not yetprepared.

C:\Windows\system32>dbtool -nosession -trans -info jpadb1VERSANT Utility DBTOOL Version 8.0.3Copyright (c) 1988-2014 VERSANT Corporation

** Short transaction Info **

-----------------------------------------------------------------------------------------Tx ID Coord count flags server[pid.tid] client[pid name] session-name long trans ID----------------------------------------------------------------------------------------2978.0.6153 y 00001 x88290 06728.08148 07804 user V/JPA

The flags x88290 indicate an XA transaction branch which is externally managed and not yetprepared.

C:\Windows\system32>dbtool -nosession -trans -info e516VERSANT Utility DBTOOL Version 8.0.3Copyright (c) 1988-2014 VERSANT Corporation

** Short transaction Info **

-----------------------------------------------------------------------------------------Tx ID Coord count flags server[pid.tid] client[pid name] session-name long trans ID----------------------------------------------------------------------------------------2981.0.155655 y 00001 x88292 dead Cobra SessionCoordinator of this dead Tx = e516No. of participants involved in this dead Tx = 0

The flags x88292 indicate an XA transaction branch which is prepared. In the above case, it isreported as a dead transaction because the process which started the transaction is no longerconnected to the database server.

69Versant JPA Developer's Guide

Identifying Dead Transactions

The following table lists the responsibilities taken by the different V/JPA transaction classificationtypes for dead transactions.

PreparedNot-yet-preparedstate does not existnever reported as deadNative resource-localRecovery logic folded into theV/JPA client libraries takes care

never reported as deadNative distributed

of this when starting a newtransaction

The external XA TransactionManager gets these reported andhas to resolve them

Transaction will be rolled backautomatically by the VersantJPA Server, when another

XA

transaction is started and thedefined timeout for thistransaction was reached

Note, that resource-local native transactions as well as not-yet-prepared native distributedtransactions are never reported as dead. The Versant JPA Server will automatically address suchtransactions in the case of an abnormal client termination.

Versant JPA Developer's Guide70

Identifying Dead Transactions

Chapter 10. Schema Evolution

Sections• Enabling Schema Evolution• Fields• Class Hierarchy

Versant JPA Server has the ability to evolve schema definitions andmigrate instances of an existingclass version.

The following are the possible schema evolution operations.

• Addition of an attribute to a class and all subclasses.

• Removal of an attribute from a class and all subclasses.

• Changing the field type of an attribute in a class.

• Addition of a subclass to a class.

• Addition of a superclass to an inheritance tree.

• Removal of a superclass from an inheritance tree.

• Moving a field one level up or down within classes of an inheritance hierarchy.

• Modifying the inheritance hierarchy by insertion of a new class between a superclass and asubclass.

• Modifying the inheritance hierarchy by dropping a class between a superclass and a subclass.

10.1. Enabling Schema EvolutionTo enable schema evolution, set the persistence unit property versant.schemaEvolve to true (thedefault is false). Schema evolution is independent from schema definition. If a new entity class isintroduced, it is defined in the schema, or not, depending on the setting of the versant.schemaDefineproperty (refer to versant.schemaDefine pg. 11).

71Versant JPA Developer's Guide

If schema evolution is not enabled (versant.schemaEvolve is false) and any of your entity classdefinitions differ from the established database schema, an exception is thrown when you createthe entity manager factory.

(Versant JPA also provides a schema loose mapping mechanism that will allow limited mis-matchesin client/server schemas. Refer to Section 11.2, “Schema Loose Mapping” pg. 89 for a description.)

10.2. FieldsThe actions whichmodify the class signature are adding or deleting one or more fields or changingthe type(s) of a field or fields.

Consider a data model, modelA, with classes Person, Employee and Address. Following are the classdefinitions.

modelA

@Entityclass Person {@Idlong loid;

String name;}

@Entityclass Employee {@Idlong loid;

float salary;}

@Entityclass Address {@Idlong loid;

String street;

Versant JPA Developer's Guide72

Fields

String city;String zip;

}

And here is the persistence.xml file for this data model.

<persistence-unit name="unit1" transaction-type="RESOURCE_LOCAL"><class>Person</class><class>Employee</class><class>Address</class><properties><property name="versant.connectionURL" value="db1" /><property name="versant.schemaDefine" value="true" />

</properties></persistence-unit>

The db2tty tool is used to view the contents of the database specified. You can verify the classdefinitions using the following command.

db2tty -D database -s

Adding a field

Let us now change modelA, defined above, to modelB where a new field age is added to Person andnew field address of type Address is added to Employee. This will result in the following definition.

modelB

@Entityclass Person {@Idlong loid;

String name;int age;

}

73Versant JPA Developer's Guide

Fields

@Entityclass Employee {@Idlong loid;

float salary;Address address;

}

@Entityclass Address {@Idlong loid;

String street;String city;String zip;

}

This is the persistence.xml file for modelB.

<persistence-unit name="unit1" transaction-type="RESOURCE_LOCAL"><class>Person</class><class>Employee</class><class>Address</class><properties><property name="versant.connectionURL" value="db1" /><property name="versant.schemaEvolve" value="true" />

</properties></persistence-unit>

The original class definition and instances in modelA can now be evolved according to the modifieddefinition, modelB.

To evolve the schema, start the application again. You can use the db2tty utility to see the newfields that were added to the schema definition. Call db2tty -D database -s.

====== CLASS 'Person' ======[no superclasses]attributes:

Versant JPA Developer's Guide74

Fields

o_ts_timestamp : o_4bname : char[]age : o_4b

====== CLASS 'Employee' ======[no superclasses]attributes:o_ts_timestamp : o_4bsalary : o_floataddress -> Address

Adding a field to a superclass will add it to all its subclasses.

Removing a field

Consider the following change to the original model, modelA, defined above. In this example, anexisting attribute, zip, is removed from the Address class. This will result in the following definition.

modelC

@Entityclass Person {@Idlong loid;

String name;}

@Entityclass Employee {@Idlong loid;

float salary;}

75Versant JPA Developer's Guide

Fields

@Entityclass Address {@Idlong loid;

String street;String city;// removed String zip;

}

The persistence.xml file will be same as for modelB, above.

The original class definition and instances in modelA can now be evolved according to the modifieddefinition. To evolve the schema, start (or re-start) the application. The zip field will be removedfrom Address. Again, you can use db2tty -D database -s to see that the field is removed from theschema definition.

Removing a field from a superclass will remove it from all its subclasses.

Changing the data type of a field

Let us now change the original model, modelA, to modelD where we change the data type of anexisting salary field in the Employee class from float to int. This will result in the following classdefinitions.

modelD

@Entityclass Person {@Idlong loid;

String name;}

@Entityclass Employee {

Versant JPA Developer's Guide76

Fields

@Idlong loid;

int salary; // was type float}

@Entityclass Address {@Idlong loid;

String street;String city;String zip;

}

The persistence.xml file will be same as for modelB, above.

The original class definition and instances in modelA can now be evolved according to the modifieddefinition in modelD as before, by starting or re-starting the application. The data type of the salaryfield is changed from float to int in Employee. Call db2tty -D database -s to see the changed fieldin the schema definition.

====== CLASS 'Employee' ======[no superclasses]attributes:o_ts_timestamp : o_4bsalary : o_4b

In effect, when you change the type of a field, the original named field is deleted and a new fieldwith the same name and the new type is introduced in the schema. The result is that the previouscontents of the field are lost for existing instances of the class. When these instances are loadedinto the application using the updated schema, the field will initially have the default value for thenew data type.

77Versant JPA Developer's Guide

Fields

10.3. Class HierarchyThe actions which modify the inheritance hierarchy of a class are adding, removing or changingthe superclass or inserting of a new class between a superclass and a subclass.

Let us redefine modelA.

modelA

@Entityclass Person {@Idlong loid;

String name;}

This is the persistence.xml file for modelA.

<persistence-unit name="modelA" transaction-type="RESOURCE_LOCAL"><class>Person</class><properties><property name="versant.connectionURL" value="db1" /><property name="versant.schemaDefine" value="true" />

</properties></persistence-unit>

To define this model start the application.

You can verify the definitions using db2tty -D database -s.

Adding a Subclass

Let us now change the modelA, defined above, to modelB by adding a subclass Employee to Person.This results in the following definition.

Versant JPA Developer's Guide78

Class Hierarchy

modelB

@Entityclass Person {@Idlong loid;

String name;}

@Entityclass Employee extends Person {

float salary;}

This is the metadata for modelB.

<persistence-unit name="modelA" transaction-type="RESOURCE_LOCAL"><class>Person</class><class>Employee</class><properties><property name="versant.connectionURL" value="db1" /><property name="versant.schemaEvolve" value="true" />

</properties></persistence-unit>

The original class definition and instances inmodelA can now be evolved according to themodifieddefinition as in modelB.

Re-start the application to evolve the schemaThis will add the subclass Employee to the class Person.Call db2tty -D database -s to see the subclass added in the schema definition.

====== CLASS 'Person' ======[no superclasses]attributes:o_ts_timestamp : o_4bname : char[]

====== CLASS 'Employee' ======

79Versant JPA Developer's Guide

Class Hierarchy

superclasses:'Person'attributes:o_ts_timestamp : o_4bname : char[]salary : o_4b

Adding a Superclass

Now change modelA, defined above, to modelC adding a superclass, AbstractPerson to Person. Thisresults in the following definition.

modelC

@Entityclass AbstractPerson {@Idlong loid;

char gender;Date dateOfBirth;

}

@Entityclass Person extends AbstractPerson {// @Id// long loid; (now inherited)

String name;}

Here is the persistence.xml file for modelC.

<persistence-unit name="modelA" transaction-type="RESOURCE_LOCAL"><class>AbstractPerson</class><class>Person</class><properties><property name="versant.connectionURL" value="db1" /><property name="versant.schemaEvolve" value="true" />

Versant JPA Developer's Guide80

Class Hierarchy

</properties></persistence-unit>

The original class definition and instances of modelA can now be evolved according to the modifieddefinition in modelB by re-starting the application. This will add the superclass AbstractPerson tothe class Person. Call db2tty -D database> -s to see the superclass added in the schema definition.

====== CLASS 'Person' ======superclasses: 'AbstractPerson'attributes:o_ts_timestamp : o_4bdateOfBirth : o_timestampgender : o_u2bname : char[]

====== CLASS 'AbstractPerson' ======[no superclasses]attributes:o_ts_timestamp : o_4bdateOfBirth : o_timestampgender : o_u2b

The superclass fields in AbstractPerson will be inherited in Person and all its subclasses.

Removing a Class

A schema evolution operation may involve removing a class. The class can be anywhere within theclass hierarchy, i.e., at the top (a super-class that inherits from no other application classes), inthe middle (it inherits from a super-class and has children that inherit from it) or at the bottom (aclass with no other classes inheriting from it). To remove a class from your current schema willrequire two steps. First, youwill update the existing database schema. Second, the dropclass utilityis used to remove instances of the removed class.

Removing a class from an established hierarchy requires some care. You are responsible for isolatingthe class that will be removed (dropped) from the schema. An isolated class is one that is completely

81Versant JPA Developer's Guide

Class Hierarchy

un-referenced. That is, there are no references to objects of the isolated class from other objects.Failure to fix any references to objects of the to-be-removed classwill result in “dangling references”.

Be aware that isolating a classmay not be as simple as it first appears. For example, consider a classinheritance hierarchy that defines the classes Person and Employee where Employee is a sub-classof Person. Just fixing the references in objects of classes that reference Employee directly may notnecessarily find the object references to Person objects that are, in fact, Employee objects.

Also, if you remove a class that has derived (sub-) classes, the fields defined in the dropped classare also removed from the derived classes. For example, consider the following simple class hierarchy.

class A {int numberA;

}

class B extends A {int numberB;

}

class C extends B {int numberC;

}

You can see that objects of class C will have all three fields, numberA, numberB and numberC. If classB is dropped, class C will no longer have a numberB field. Further, class C will inherit directly fromclass A (and retain the numberA field).

The following shows the use of schema evolution and the dropclass utility to remove a class, asuper-class in this case, from the schema and database.

Assume you are starting with a data model, modelA, consisting of classes Person and Employee.

modelA

@Entityclass Person {@Idlong loid

String name;}

Versant JPA Developer's Guide82

Class Hierarchy

@Entityclass Employee extends Person {

float salary;}

This is the persistence.xml file for modelA.

<persistence-unit name="modelA" transaction-type="RESOURCE_LOCAL"><class>Person</class><class>Employee</class><properties><property name="versant.connectionURL" value="db1" /><property name="versant.schemaEvolve" value="true" />

</properties></persistence-unit>

Now you change modelA, defined above, to modelB where you remove the super-class Person. Thiswill result in the following definition.

modelB

@Entityclass Employee {@Idlong loid // no longer inherited!

float salary;}

This is the persistence.xml file for modelB.

<persistence-unit name="modelA" transaction-type="RESOURCE_LOCAL"><class>Employee</class><properties><property name="versant.connectionURL" value="db1" /><property name="versant.schemaEvolve" value="true" />

83Versant JPA Developer's Guide

Class Hierarchy

</properties></persistence-unit>

The original class definition and instances in modelA can now be evolved according to the modifieddefinition in modelB by re-starting your application. This will remove the superclass Person fromEmployee.

You can call db2tty -D databaseName -s to see the changed schema definition.

====== CLASS 'Person' ======[no superclasses]attributes:o_ts_timestamp : o_4bname : char[]

====== CLASS 'Employee' ======[no superclasses]attributes:o_ts_timestamp : o_4bsalary : o_4b

Notice that the Employee class has no superclasses. And the Person class is still registered in theschema.

Once the schema is updated, you can drop the instances of the removed class, in this example,Person.

dropclass -d databaseName Person

This will also remove the Person entry from the schema.

It is very important that your application class model and the schema model are in agreement. Ifyour data model still contains the Person class, the class will be re-instated in the schema the nexttime you run your application.

Versant JPA Developer's Guide84

Class Hierarchy

Moving a field within a hierarchy

Assume the following data model, modelA, consisting of the class Person and a subclass of person,Employee.

modelA

@Entityclass Person {@Idlong loid;

String name;Date dateOf Birth;

}

@Entityclass Employee extends Person {

int salary;}

Now change the model, moving the field attribute dateOfBirth from the parent class, Person, toEmployee. Here is the new class model.

modelB

@Entityclass Person {@Idlong loid;

String name;}

@Entityclass Employee extends Person {

Date dateOfBirth; // was a Person field

85Versant JPA Developer's Guide

Class Hierarchy

int salary;}

Re-starting your application will evolve the schema. The original attribute values, now directly inthe Employee instances, are retained.

Versant JPA Developer's Guide86

Class Hierarchy

Chapter 11. Application Evolution

Sections• Using Application Evolution• Schema Loose Mapping

- Enabling Schema Loose Mapping- Schema Compatibility for Loose Mapping- Default Values for Added/Removed Fields- Examples

In a distributed system, dealing with data model, i.e., schema, changes can be troublesome. Theactual update of the schema in your Versant JPA Server databases is not a problem (refer toChapter 10, Schema Evolution pg. 71). However, updating the many clients that are using thosedatabases can rarely, if ever, occur at the moment the database schema changes. You need to keepeverything up and running as the the new clients, using the new data model, are distributed. Youneed a mechanism for application evolution that allows applications that still use an earlier schemato connect to the databases whose schema has evolved.

When aV/JPA client connects to a database, the datamodel (schema) of the application is comparedto the schema of the database. If they do not agree, the client application will generally encounteran exception generated by theV/JPA runtime. You can avoid the exception by setting the applicationproperty versant.schemaEvolve. With this property, the different schema of the client will causethe database schema to change, to evolve, to reflect those differences.

Using a client with the new data model and the versant.schemaEvolve property set is the generalmechanism for performing database schema evolution. However, this should be done in a controlledway for systems that need to stay online. If all of your client applications had theversant.schemaEvolve property set, each time a mis-match occured the version of the schema onthe client would simply force database schema evolution and your database schema would bebouncing back and forth between the schema versions that exist “out in the field”.

11.1. Using Application EvolutionTo allow your clients to be updated over time, while still continuing to run using an evolved database(butwithout evolving the schema themselves) your clients can use the application evolution propertyversant.schemaLooseMapping. As the name implies, application evolution involves a loosemapping,

87Versant JPA Developer's Guide

or coupling, between the schema known to the client and the database schema. Using loosemapping,clients will continue to use their version of the schema when connecting to a database whoseschema is different. Of course, the clients using the older schema will not have access to new fieldsor classes defined in the newer schema. And they will have to be able to deal with schema changesthat mean a field or class they know about is now gone. However, if you keep a few things in mind,application evolution via loose schemamapping can be very valuable for high-availability systemswith distributed applications that simply cannot be updated all at once.

The following figure shows the basic schemamodes usedwith application evolution. (Also, a simpleexample showing application evolution is provided with your V/JPA installation in thevjpa2/examples/jpa_app_evolve directory. Follow the instructions in the readme file, there.)

Figure 11.1. Application Evolution—Schema Modes

There is a single client, Client A, that has schema evolution set, i.e., the versant.schemaEvolveproperty is set to true in the persistence unit. Client A receives the schema information from the

Versant JPA Developer's Guide88

Using Application Evolution

database(s) and can send schema updates. This client may be under the control off a systemadministrator, for example, and connects expressly for the purpose of evolving the database schema.All other clients are using runtime application evolution. In their persistence unit files, the propertyversant.schemaLooseMapping is set to runtime. They will receive the schema information andcontinue to run if they detect a schema mis-match. But they will not cause the database schemasto evolve.

Things to keep in mind

Even though clients with a mis-matched schema continue to run, they must re-read the newschema from the server(s). If you have a very complex data model, this can take some

time—perhaps many seconds for schemas containing thousands of classes. This can cause a delayin the response time for the client application.

If your clients connect to multiple databases, these delays may be compounded. Since all of thedatabases will not have the new schema at exactly the same time, the client may performmultipleschema transfers as the client connects to the databases. For this special case, the persistenceunit property versant.schemaLooseSyncTimeout can be used to avoid redundant schema transfers.Refer to versant.schemaLooseSyncTimeout pg. 13 for details.

• Your application will have to take into consideration the way loose mapping handles new anddeleted fields and classes for both your new and old clients. Also, not all mis-matches can becorrectly handled using loose mapping. The following section describes these considerationsand discusses schema loose mapping in more detail.

11.2. Schema Loose MappingRunning your applications with schema loose mappingmeans that they can continue to work evenif the entity class definitions differ from the database schema. In the previous section, you saw howthis works based on a typical use case. This section will explain how loose mapping works in moredetail.

Runtime vs. Startup

The client compares its version of the schemawith that on the server-side when creating the entitymanager factory and when starting a transaction.With runtime loosemapping enabled, if a versionmis-match is found, the client re-loads the schema from the server. You can also specify that theclient may load new schema information only at startup, that is, when creating the entity managerfactory. If you specify only startup schema updates, changes to the schema detected at transaction

89Versant JPA Developer's Guide

Schema Loose Mapping

begin will generate an exception. (This could be of use if your application can start with a knownmis-match butmight be sensitive to schema changes that occur after creation of the entitymanagerfactory.)

Preserving values

A schema change may involve the addition of entity attributes (class fields). If a client using loosemapping receives a new schema where an entity has additional attributes that are not present inthe client data model, reading such an entity is not a problem, the client simply does not “see”these new attributes. However, if the client modifies the entity, what is the state of any unknownattributes when the entity is written back to the database? V/JPA provides two behaviors. You canchoose to write any unknown attribute as a default value or you can retain the value that theunknown attribute had when it was read. The default values used are described in Section 11.2.3,“Default Values for Added/Removed Fields” pg. 92, below.

11.2.1. Enabling Schema Loose Mapping

To enable loose mapping, set the persistence unit property versant.schemaLooseMapping to thedesired behavior. (The default is off.) The allowed property values are as follows.

off (the default)runtimestartupruntime_preserve_valuesstartup_preserve_valuesThe property values runtime and startup specify runtime or startup schema update behavior (referto Section 11.2, “Runtime vs. Startup” pg. 89) using default values for unknown attributes. Tospecify the preserve values behavior, use runtime_preserve_values or startup_preserve_values.

Here is an example persistence unit setting loose mapping with the runtime and preserve valuesbehaviors.

<persistence-unit name="unit1" transaction-type="RESOURCE_LOCAL">. . .<properties><property name="versant.schemaLooseMapping" value="runtime_preserve_values" /><property name="versant.schemaDefine" value="false" /><property name="versant.schemaEvolve" value="false" />

Versant JPA Developer's Guide90

Schema Loose Mapping

</properties></persistence-unit>

Loose mapping is, in effect, a directive to not allow the client to alter the schema. Therefore, loosemapping cannot be set if either versant.schemaDefine or versant.schemaEvolve is true (anexception is thrown).

11.2.2. Schema Compatibility for Loose Mapping

Not all schema differences can be handled by loose mapping. The schema differences are checkedfor compatibility with loose mapping whenever an updated schema is loaded by the client. Ifincompatible schema differences are detected, an exception is thrown. When using schema loosemapping, the application must access the database from within a transaction. Accessing entitiesoutside of a transaction will cause an exception if a schema change is detected.

The following categorizes the schema modifications that loose mapping can handle or not. If amodification that cannot be handled by loose mapping is detected, an exception is thrown whenyou create the entity manager factory.

Supported modifications

• add or remove a field in a class

• move a field from one class to another within a hierarchy (max. one level up or down)

• add or remove a leaf class within a hierarchy

• add or remove a class at the top of the hierarchy

Unsupported modifications

• change the type of a field

• add or remove a class within a hierarchy

91Versant JPA Developer's Guide

Schema Loose Mapping

11.2.3. Default Values for Added/Removed Fields

Clients with older versions of a schema and using loose mapping will not see an added field whenreading entities from the database. If the client creates a new entity, the unknown field will havea default value (see the table below). If the client modifies an entity and writes it back to thedatabase, the added field will also have a default value unless you specify the preserve valuesbehavior.

If you are not using the preserve values behavior, a default value written from the “older” clientcan potentially overwrite the attribute content if the entity was written by a “newer” client.

An “older” client that reads an entity with a removed field will see the default value for the field(listed below). Removed fields will not be written to the database by “older” clients.

ValueType0byte, char, short, int, long, float, double

falseboolean

nullsql.Date, util.Date, Timestamp, Time

nullString, wrapper classes, arrays, collections, entities

11.2.4. Examples

A couple of simple examples, one, adding a new field to a class and another adding new classes,will help make the operation of loose mapping clear. First, assume an existing, populated databaseis using the following original data model, modelA-v1, for the Person class.

modelA-v1

@Entityclass Person {@Idlong loid;

String name;}

Versant JPA Developer's Guide92

Schema Loose Mapping

Anapplication using the following evolved schema (modelA-v2) is startedwith versant.schemaEvolveset to true.

modelA-v2

@Entityclass Person {@Idlong loid;

String name;boolean married; // new field

}

The database schema now has an additional field for the Person class.

Starting an application that uses modelA-v1 and loosemapping enabled will work. If a new instanceof Person is stored, the default value, false, for the married field will be written to the database.Writing instanceswhichwere createdwith modelA-v2, and then loaded andmodifiedwith modelA-v1,will either overwrite the field with the default value for the type ( runtime or startup) or the readvalue if preserve values behavior is used (versant.schemaLooseMapping set toruntime_preserve_values or startup_preserve_values).

Now, another example, introducing new classes to the schema. The original schema is modelB-v1.

modelB-v1

@Entityclass Person {@Idlong loid;

String name;boolean married;

}

The evolved schema modelB-v2 has two additional classes (and new fields and inheritance).

93Versant JPA Developer's Guide

Schema Loose Mapping

modelB-v2

@Entityclass Person {@Idlong loid;

String name;boolean married;Address address;

}

@Entityclass Employee extends Person {int salary;

}

@Entityclass Address {@Idlong loid;

String street;String city;String zip;

}

An application using loosemapping and runningwith modelB-v1will now store new Person entitieswith null for the address field. The value of addresswhen updating instances that were previouslywritten by an application that is based on modelB-v2 and had a value for address is dependent onwhether preserve values behavior used, as in the previous example. (Since, older clients will nothave the Address or Employee classes in their data model, they cannot read or create instances ofthese classes.)

Versant JPA Developer's Guide94

Schema Loose Mapping

Chapter 12. Entity Identity

Sections• Allocation of Logical Object Identifiers• Using the Entity Identifier in Queries

In the Versant JPA datastore, each entity has a unique identifier, the LOID or Logical ObjectIDentifier, that never changes for the life of the entity (and is never re-used). This LOID is also theprimary key for your V/JPA entities and is the value of the @Id field. (Refer to Section 23.1, “PrimaryKeys and Object Identifiers” pg. 159 for the rules related to the @Id field in V/JPA.)

The Versant JPA datastore LOID is a 64-bit number (Java type long or java.lang.Long). Thehigh-order 16 bits represent the database (in a distributed database environment) and the low-order48 bits form the unique entity identity in the database.

This is referred to as the logical identifier to differentiate it from any internal representation forthe entity used by the physical datastore. Since the logical identifier is used as the primary key inyour V/JPA application it satisfies the requirement that the key be a unique identifier for the entity.

12.1. Allocation of Logical Object IdentifiersBecause the LOID is unique for each entity in a given database and must represent the entity forits lifetime in the database, Versant JPA is responsible for allocating these values. When you createan entity manager factory a connection to the database server is made and the server will return apre-allocated batch of identifiers. By default, these identifiers are allocated in blocks of 1024.Whenmore identifiers are needed, a request is sent to the V/JPA server and a new batch of identifiers isreturned.

If you are creating very large numbers of entities in the transactions associated with the entitymanager factory the requests for additional batches of identifiers can result in a small, butnevertheless measurable, performance reduction. If you know that a significantly large number ofidentifiers will be needed, you can instruct the entity manager factory to request batches in blocksof an appropriate size.

95Versant JPA Developer's Guide

Adjusting the LOID Batch Size

The default LOID batch size is 1024. You can change this with the persistence unit propertyversant.defaultLoidBatchSize. For example, the followingwould cause the entitymanager factoriesto fetch identifiers in batches of 500000.

persistence.xml

<persistence version="2.0"><persistence-unit

name="my_persistence_unit"transaction-type="RESOURCE_LOCAL">

. . .<properties>

<propertyname="versant.defaultLoidBatchSize"value="500000" />

</properties></persistence-unit>

</persistence>

The value specified by the property applies to all databases opened by the entity manager factoriescalling the persistence unit.

You can also change the batch size at runtime with the VersantEntityManagerFactorymethodsetLoidBatchSize(Database database, int loidBatchSize). This method adjusts the batch sizefor the specified database in the calling entity manager factory. You can set the database argumentto null to refer to the first (or only) database in the list of open databases. (Refer to Chapter 5,Distributed Databases pg. 47 for information about using multiple databases.)

This example sets the LOID batch size to 500000 for the first (or only) connected database in thecalling entity manager factory.

VersantEntityManagerFactory emf = (VersantEntityManagerFactory)Persistence.createEntityManagerFactory("my_persistence_unit");

emf.setLoidBatchSize(null, 500000);

The value you specify with setLoidBatchSize() overrides any value set with theversant.defaultLoidBatchSize property (or the default if the property is not set). The specifiedbatch size will take effect the next time the factory requests a LOID batch, i.e., when the current

Versant JPA Developer's Guide96

Allocation of Logical Object Identifiers

batch is exhausted. The value stays in effect until you specify a different value (with another callto setLoidBatchSize()) or the factory is closed.

If your application will only occasionally need a large number of identifiers, you should use theruntime setLoidBatchSize() method and be sure to return the batch size to a reasonable valuewhen appropriate. Though 2^48 is a very large number, you could inadvertently deplete the availableidentifiers if every fetch results in, for example, millions of identifiers that may not be used.

In any case, use care when adjusting the LOID batch size, especially when changing the defaultusing the persistence unit property. Very small values can result in excessive requests for additionalbatches with a potential negative impact on application performance.

12.2. Using the Entity Identifier in QueriesIn Versant JPA, the entity identity, or LOID, is handled in a different fashion from other attributeswhen making query comparisons. The LOID(s) you pass to the WHERE clause essentially definethe extent of the FROM clause when the query is run. This places some restrictions on the ways inwhich the LOID can be used.

The following rules apply. Assume a query in the form SELECT...FROM Student s...

• Only the top-level comparisons are supported. That means an expression such as WHEREs.department.id = 12345 is not allowed.

• Input parameters are supported. The parameter must resolve to an int or long type.

For example, the following are valid (the parameter i is int or long)

WHERE s.id = :iWHERE s.id IN (12345,:i)WHERE s.id IN :i // here, parameter i is a list of int or long

• Only the EQUALS (=) and IN operators are supported.

For example, the following are allowed

WHERE s.id = 12345WHERE s.id IN (12345,67890)

The following are not allowed

97Versant JPA Developer's Guide

Using the Entity Identifier in Queries

WHERE s.id != 12345WHERE s.id > 12345

• The LOID comparison may be a sub-expression in an AND construct but not of an OR or NOTconstruct.

For example, the following are allowed

WHERE s.id IN (12345,67890) AND s.id IN (12345,54321)WHERE s.id IN (54321,67890) AND (s.name='Max' OR s.age=42)WHERE (s.id IN (54321,67890) AND s.name='Max') OR s.age=42

The following are not allowed

WHERE NOT s.id = 12345WHERE s.id = 12345 OR s.id IN (54321,67890)

Versant JPA Developer's Guide98

Using the Entity Identifier in Queries

Chapter 13. Collections and Maps

Sections• Collection Optimization• Map Behavior

The Versant JPA provides an optimized implementation of collection and map types. Theseoptimizations are discussed in the following sections.

13.1. Collection OptimizationIn order to optimize working with collection, Versant JPA provides the ability to use the entityidentitywhen determining collectionmembership. The usualmechanism for determiningwhether,for example, a collection contains a particular entity is to use the equals()method. Using the entityidentity (the @Id field value) for such comparisons is much more efficient.

When you read an entity that contains a collection field from the database, only the entity identitiesfor the collection elements are loaded. The elements themselves are lazy-loaded, i.e, only loadedon-demand. (You can change this behavior with FetchType=FetchType.EAGER. The default isFetchType.LAZY) If a collection uses the equals() method for entity comparison, the collectionelements must be loaded when performing many operations on the collection. By using the entityidentity for comparisons you can get around loading the element entities.

To specify that a collection use the entity identity for comparisons, V/JPA provides a vendor-specificannotation, @EqualsById. The following shows an example.

public class Book {. . .@EqualsByIdSet<Person> authors;. . .

}

99Versant JPA Developer's Guide

The @EqualsById annotation is supported for Set and Map types and applies to themethods of thoseclasses that perform entity comparisons. (Refer to Table 13.1, “@EqualsById—Supported Classesand Methods” pg. 100 for the supported classes and methods.)

For collections using @EqualsById, the identity of the entity determineswhether the entitymatchesanother in the collection. If you are relying on the equals()method to determine if two objects arethe same (e.g., objects with the same content are equal) the @EqualsById annotation will likely notbe appropriate. Use the @EqualsById annotation only for collections where the entity identitycomparison satisfies your requirements.

Newly-created entities added to a collection using @EqualsById are immediately made persistent.The persist operation assigns the entity identity which is needed for entity comparison. Since thenew entities are made persistent, they add to the number of modified entities in the transaction.This could trigger auto-flushing if a large number of elements are added to the collection in a singletransaction. (Refer to Chapter 7, Automatic Flushing pg. 57 for information about auto-flushing inV/JPA.)

Table 13.1. @EqualsById—Supported Classes and Methods

MethodsClassSet add()

addAll()contains()containsAll()remove()removeAll()retainAll()

Map put()putAll()containsKey()remove()

13.2. Map BehaviorVersant JPA optimizes the loading of Map and HashMap fields. When you load a persistent entity thatcontains a map field, when the map keys and map values are resolved is dependent on the types ofthe map key and value components. The type may be a primitive (int, String, etc.) or an entityreference. And the @EqualsById annotationwill also influencewhen themap elements are resolved.

Versant JPA Developer's Guide100

Map Behavior

The following rules determine when components of the map, or hash map, are actually read fromthe server.

• Map keys and map values of primitive types (i.e., not references to other entity instances) areread when the entity containing the map is read.

• Map values of entity reference type are individually resolved and loaded when the map elementis accessed with the get(key)method.

• Map keys that are entity references are either loaded all together or not at all depending on theuse of the @EqualsById annotation (refer to Section 13.1, “Collection Optimization” pg. 99 for adiscussion of @EqualsById).

– Using @EqualsById allows the use of themethods listed inTable 13.1, “@EqualsById—SupportedClasses andMethods” pg. 100without the need to load the entities referenced by themap key(s).

– If @EqualsById is not applied to themap field, any access to themapwill cause all reference-typemap keys to be loaded.

101Versant JPA Developer's Guide

Map Behavior

Versant JPA Developer's Guide102

Chapter 14. Fetch Strategies

Sections• Eager loading• Entity Graphs• Burst-Fetch

A fetch strategy refers to bringing additional entities intomemory based on a “trigger”. This triggercan be the resolution of a specifc object, e.g., a root object triggers automatic loading of its referencedobjects. It can be class-based, e.g., resolving an object of a given class triggers loading all objectsof that class. The strategy can be that loading objects having certain relationships with other objectstrigger loading all objects with the same relationship, etc. The purpose of a fetch strategy is toincrease your application's performance by reducing network requests. A fetch strategy loadsmultiple objects based on the anticipation that they will also be needed by the application.

The following sections look at the the V/JPA strategy burst-fetch and the JPA strategies eagerloading and entity graphs.

14.1. Eager loadingNormally, when navigating from an entity to other not-yet-loaded entities, the not-yet-loadedreferenced entities are transparently fetched as they are accessed. In other words, references arelazy-loaded. This is the behavior you want when your application has no anticipatory knowledgewhether a referenced object will be needed or not. Assume the following example class definition.

@Entity class Person {List<Address> addresses;

}

Now assume you are working with, say, ten Person entity instances within a transaction. If youaccess the Address collections of those instances, there is a client-server round-trip in order tofetch the lists of addresses. If you end up accessing all of the address lists, that is a round-trip foreach of the ten Person entities. If you know up-front that you also need the list of addresses foreach person, one way you may optimize this is to annotate the addresses attribute withFetchType.EAGER.

103Versant JPA Developer's Guide

@Entity class Person {@OneToMany(fetch=FetchType.EAGER)List<Address> addresses;

}

Now, when the Person instance is loaded, the address list is loaded as well. This is fine if you knowyou will want the person's addresses. But what if your application onlymay need all of the addresslists? That is where burst-fetch would apply.

14.2. Entity GraphsUsing FetchType.EAGER allows you to optimize one access pattern with respect to the loadoptimization provided by the database. However, the eager annotation does not address the casethat different, potentially contradicting, access patterns may be useful to the application. For thisreason, the JPA 2.1 specification introduced the concept of entity graphs to either override(javax.persistence.fetchgraph) or augment (javax.persistence.loadgraph) eager loadingbehavior.Entity graphs can be used in find or query operations to load pre-specified object networks associatedwith the result set objects. (Unlike the EAGER specification, entity graphs do not affect normal objectnavigation.)

To demonstrate the use of an entity graph, first, consider the example using FetchType.EAGER fromthe previous section.

@Entityclass Person {@OneToMany(fetch=FetchType.EAGER)List<Address> addresses;

}

You can define an entity graph to achieve the same load rule.

@NamedVersantEntityGraph(name="fetchGraph1",attributeNodes={@NamedVersantAttributeNode("addresses")})

@Entity class Person {

Versant JPA Developer's Guide104

Entity Graphs

List<Address> addresses;}

Defining an entity graph can be done via annotations, as shown here, or as elements in the XMLmetadata. Formore information regarding the entity graph syntax, refer to the JPA 2.1 specificationor any of the many available JPA reference sources.

The Versant JPA entity graph implementation

The V/JPA implementation renames the JPA annotations (e.g., NamedVersantEntityGraph in theabove example rather than NamedEntityGraph). For more information and an explanation of whythis is the case, refer to Section 23.3, “Entity Graphs” pg. 160.

This entity graph, above, may be used in a find or query operation as shown in the followingexamples.

Find operation

Map<String,Object> props = new HashMap<String,Object>();props.put("javax.persistence.fetchgraph", "fetchGraph1");obj = em.find(null, loid, props);

Query operation

q = em.createQuery("select x from Person x");q.setHint("javax.persistence.fetchgraph", "fetchGraph1");list = q.getResultList();

For an in depth discussion of entity graphs, refer to the JPA 2.1 specification or other third-partyreference material.

14.3. Burst-FetchWith eager loading, referenced entities are loaded with their parent. Burst-fetch provides analternative strategywhen your applicationmaynot always need the referenced entities. For example,you may or may not need the addresses of the person instances, but if the addresses are neededyou will want them for all person instances in the persistence context.

105Versant JPA Developer's Guide

Burst-Fetch

Here is the class model from the eager loading section, above.

@Entity class Person {List<Address> addresses;

}

If burst-fetching is enabled, when the addresses attribute of a Person entity is accessed—and theattribute is not already loaded—then for all other Person entities, in the same persistence context,the addresses that have not been loaded are loaded and resolved along with the values for theattribute of the entity which triggered the loading process.

For the example above, this means that once the addresses attribute of the first Person entity isaccessed, the addresses for the other nine persons are also fetched and the respective collectionsare created and populated.

Burst-fetch operates on the set of same-typed entity instances contained in the persistence contextat the point when the fetch is started. It is not extended to same-typed entity instances beingbrought into the persistence context during this operation.

You can enable burst-fetch globally in the persistence unit (persistence.xml file), for a specificentity manager factory or for a specific entity manager. The property name is versant.burstFetch.

• Persistence unit (global)

<property name="versant.burstFetch" value="true" />

• Entity manager factory

Map<String, String> props = new HashMap<String, String>();props.put( "versant.burstFetch", "true" );Persistence.createEntityManagerFactory( props );

• Entity manager

EntityManagerFactory emf = . . .Map<String, Object> props = new HashMap<String, Object>();props.put( "versant.burstFetch", true );emf.createEntityManager( props );

Versant JPA Developer's Guide106

Burst-Fetch

The default behavior is that burst-fetch is not enabled. You can disable burst-fetch for a restrictedcontext with the property value "false". For example, if you have burst-fetch globally enabled youcan choose to disable it for a specific entity manager or manager factory.

Note, that using burst-fetch—as with all fetch strategies— just leads to unnecessary overhead ifthe additionally fetched objects are, in fact, not needed.

107Versant JPA Developer's Guide

Burst-Fetch

Versant JPA Developer's Guide108

Chapter 15. Unresolvable References

Sections• Repairing Unresolvable References• Monitoring Unresolvable References• Custom Handling of Unresolvable References

15.1. Repairing Unresolvable ReferencesAn unresolvable reference is a reference that cannot be read. It may be that the referenced entity nolonger exists in the database or it is in a database that is off-line. It is possible to inadvertentlycreate an unresolvable reference if your application removes an entity that is referenced by one ormore other entities. The normal behavior in JPA when your application attempts to resolve themissing, or otherwise unresolvable, reference is that an EntityNotFoundException exception isthrown. It is then up to you to handle the exception by repairing the reference, for example, bysetting the reference to null.

Versant JPA provides a built-in mechanism to automate the repair of unresolvable references. Byusing the property versant.unresolvableReferenceStrategy you can set the persistence unit or aspecific entity manager to use a repair mode strategy when unresolvable references are detectedrather than simply throwing an exception.

To define the repair mode strategy for a persistence unit, use theversant.unresolvableReferenceStrategy property with the value REPAIR in the appropriatepersistence.xml file.

<property name="versant.unresolvableReferenceStrategy" value="REPAIR" />

The default value for this property is THROW. This results in the normal behavior that unresolvablereferences result in an EntityNotFoundException exception.

To configure a single entity manager to use the unresolvable reference repair mode, pass theproperty/value to the factory when creating the EntityManager instance.

109Versant JPA Developer's Guide

Map<String, Object> props = new HashMap<String, Object>();props.put(

"versant.unresolvableReferenceStrategy",com.versant.jpa.repair.UnresolvableReferenceStrategy.REPAIR );

EntityManager em = emf.createEntityManager(props);

When in repair mode, the entity manager will detect unresolvable references when attempting toload entities from the database. The following repair action is performed, depending on the typeof reference.

The reference field is set to nullSingle References (@OneToOne),Arrays

The missing element is removed from the collection/array (notethat this will change the size and index mapping of thecollection/array)

Collections (@OneToMany)

If a key or a value is missing, the entire entry (key/value pair) isremoved from the map

Maps (java.util.Map)

Using the repair strategy

When using repair, all entity member access should take place inside an explicit transaction inorder that modified entities are written back to the database. Otherwise, the dirty marker willhave no effect and the persistent state will retain the unresolvable reference.

• Keep in mind that some collection operations (e.g., size(), isEmpty(), etc.) do not resolve thecollection elements from the database. This can result in seemingly inconsistent behavior. Forexample, if isEmpty() reports false for a given collection, accessing it via iterator().next()still may fail if the collection element(s) are, in fact, unresolvable references.

• Care should be taken when using the repair strategy in a production environment. Your applicationmust be implemented in a way that can respond to all effects of such runtime reference changes.An alternative to having all clients performing repairs is to have a dedicated client, using therepair strategy, that can “clean up” as needed.

• You can get and log information about unresolved references using the monitoring facilitydescribed in Section 15.2, “Monitoring Unresolvable References” pg. 111, below. A

• If you want more control over the the repair strategy or behavior other than what is provided bythe build-in repair handler, you can implement a custom handler. Custom repair handlers aredescribed in Section 15.3, “Custom Handling of Unresolvable References” pg. 113.

Versant JPA Developer's Guide110

Repairing Unresolvable References

15.2. Monitoring Unresolvable ReferencesFor logging and debugging purposes, it is possible to register a listener for occurrences ofunresolvable references. Your listener is an implementation of the UnresolvableReferenceListenerinterface. The interface and how you register your implementation are described in the followingsections.

The UnresolvableReferenceListener interface

The UnresolvableReferenceListener interface contains a single method, unresolved(), with thefollowing signature.

void unresolved(ReferenceKind referenceKind,UnresolvableReferenceInfo info,UnresolvableReferenceAction action)

This method is invoked whenever an unresolvable reference is encountered and before any activebuilt-in repair strategy is applied. The listener parameters provide your implementation with thefollowing information.

Interface parameters

referenceKind

The kind of the reference that could not be resolved. The following kinds are reported

• single reference

• array

• collection entry

• map value

• map key

111Versant JPA Developer's Guide

Monitoring Unresolvable References

info

Detailed information about the unresolvable reference including the logical identifier of thesource and target entities and the reference field type

action

The action to be performed by the active repair strategy

For more detailed information regarding the listener interface and argument types, refer to theV/JPA Javadoc API reference.

Implementations of this method should be used for reporting and logging purposes only and notthrow an exception or otherwise affect code flow.

Registering the listener

The unresolved reference listener may be registered for the application in the persistence unit(persistence.xml file), for an entity manager factory or for a specific entity manager.

For a persistence unit

Register your listener implementation using the versant.unresolvableReferenceListenerproperty in the persistence.xml file and specifying the fully qualified class name for theproperty value.

<property name="versant.unresolvableReferenceListener" value="my.Listener"/>

Each entity manager factory that specifies the persistence unit will create an instance of thelistener and that listener instance is shared by all entity managers created from the factory.

The listener class must have a default (no-args) constructor.

For an entity manager factory

Pass the fully qualified class name as a property when creating the entity manager factory.

Versant JPA Developer's Guide112

Monitoring Unresolvable References

Map<String, String> props = ...props.put("versant.unresolvableReferenceListener", "my.Listener");Persistence.createEntityManagerFactory("unitName", props);

The factorywill create the listener instance and this instance is used by all of the entitymanagerscreated from the factory.

The listener class must have a default (no-args) constructor.

For an entity manager

Pass an instance of the listener as a property when creating the entity manager.

Map<String, Object> props = ...props.put("versant.unresolvableReferenceListener", new my.Listener());emf.createEntityManager(props);

A listener instance registered to an entity manager is used by that manager.

You can only set the listener when creating the entity manager, as described above. Using thesetProperty()method has no effect.

15.3. Custom Handling of Unresolvable ReferencesYou can define your own repair strategy for unresolved reference handling. This involvesimplementing the UnresolvableReferenceHandler interface and registering your implementationas described in the following sections.

A custom handler must be used with great care in order to avoid introducing type errors. It isrecommended that you use the built-in repair strategy, described in Section 15.1, “RepairingUnresolvable References” pg. 109 above, if possible.

The built-in repair strategy and the monitoring listener cannot be used in conjunction with a customhandler. Configuring a custom handler in the same scope as the built-in repair strategy or monitoringlistener will result in an InvalidConfigurationPropertyException in the persistence unit scopeor IllegalArgumentException in the entity manager scope.

113Versant JPA Developer's Guide

Custom Handling of Unresolvable References

The UnresolvableReferenceHandler interface

The UnresolvableReferenceHandler interface contains a single method, handleUnresolved(), withthe following syntax.

Option<Object> handleUnresolved(ReferenceKind referenceKind,UnresolvableReferenceInfo info

) throws EntityNotFoundException

The information passed to the method via the referenceKind and info parameters have the samesemantics as for the UnresolvableReferenceListenerAPI as described in Interfaceparameterspg. 111,above.

Yourmethod implementation determines the action to be taken by the return value, Option<Object>.The return values for specific actions are desribed in the following list.

Option<Object> return values and actions

Option.some(x)

The missing reference will be replaced with the supplied value of x. Obviously, the runtimetype of x needs to be consistent with the type of the field/reference specified in the infoargument, otherwise this will immediately trigger a PersistenceException and leave thetransaction unchanged.

Option.some(null)

The missing reference will be set to null. This may result in a runtime exception when appliedto collections/maps that don't allow null elements/keys/values.

Option.none()

The missing reference will be removed from the collection/array. For maps, the whole entryassociated with this key or value will be removed. This will immediately yield aPersistenceException when applied to a single reference.

Exceptions thrown by the handleUnresolved() callback method are propagated as follows.

Versant JPA Developer's Guide114

Custom Handling of Unresolvable References

EntityNotFoundException

The exceptionwill be propagated to the calling client. No in-memory or persistentmodificationswill occur.

all other exceptions

The exception will be wrapped as a PersistenceException and propagated to the calling client.No in-memory or persistent modifications will occur. This behavior is a safeguard againstprogramming errors and should not be used intentionally in your application.

Registering the handler

The unresolved reference handler may be registered for the application in the persistence unit(persistence.xml file), for an entity manager factory or for a specific entity manager.

For a persistence unit

Register your handler implementation using the versant.unresolvableReferenceHandlerproperty in the persistence.xml file and specifying the fully qualified class name for theproperty value.

<property name="versant.unresolvableReferenceHandler" value="my.Handler"/>

Each entity manager factory that specifies the persistence unit will create an instance of thehandler and that handler instance is shared by all entity managers created from the factory.

The custom handler class must have a default (no-args) constructor.

For an entity manager factory

Pass the fully qualified class name as a property when creating the entity manager factory.

Map<String, String> props = ...props.put("versant.unresolvableReferenceHandler", "my.Handler");Persistence.createEntityManagerFactory("unitName", props);

The factorywill create the handler instance and this instance is used by all of the entitymanagerscreated from the factory.

115Versant JPA Developer's Guide

Custom Handling of Unresolvable References

The custom handler class must have a default (no-args) constructor.

For an entity manager

Pass an instance of the handler as a property when creating the entity manager.

Map<String, Object> props = ...props.put("versant.unresolvableReferenceHandler", new my.Handler());emf.createEntityManager(props);

A custom handler instance registered to an entity manager is used by that manager.

You can only set the handler when creating the entity manager, as described above. Using thesetProperty()method has no effect.

Versant JPA Developer's Guide116

Custom Handling of Unresolvable References

Chapter 16. Large Objects

Versant JPA provides limited support for large objects using the @Lob annotation. The JPAspecification describes the use of the @Lob annotation in conjunction with the @Basic and@ElementCollectionmapping annotations. V/JPA supports the @Basic case for serializable types(primitive wrapper types, Date, BigInteger, BigDecimal, instances of entity classes implementingSerializable, etc.). The instances are serialized using standard Java serialization.

If the serialized instance is an entity or has one or more references to entities, the entities areautomatically detached. However, when read back and de-serialized, these entities are notautomatically merged. (You must provide for merging these entities, if needed, in your applicationcode.)

Additionally, V/JPA supports mapping arrays of serializable types with the @Lob annotation. V/JPAdoes not support serialization of collections such as List, Set or Map (the @ElementCollection case).

V/JPA cannot track changes to references contained in serializable attributes. You can use the entitymanager method markDirty() to force that such instances are correctly updated in the databaseat transaction end.

117Versant JPA Developer's Guide

Versant JPA Developer's Guide118

Chapter 17. Indexes

Sections• Index Annotations• Multiple Indexes• Index Definition File• Index Inheritance• Indexing Inherited Attributes• Building Index Meta Data From Annotations• Building Index Meta Data From an Index Definition File• Database Index Synchronization, Creation and Evolution

The JPA standard does not define any indexing related constructs. As vendor-specific extensions,Versant JPA provides two mechanisms for defining class attribute indexes. You can define indexesusing class-level annotations or in an index definition file which is referenced in the persistenceunit, i.e., the persistence.xml file. (The latter is similar to the JPA-specified mapping-file propertyto reference an ORM file.)

Versant JPA supports non-unique B-tree indexes. Indexes on @Id and @Version attributes are notsupported. Indexes must be named and if a given class has more than one index the index namesmust be unique.

As mentioned above, an index is defined in a class annotation or in an index definition file. Youcan mix the two approaches with some indexes defined in the class and others in the definitionfile. Index annotations and index definition files are described in the following sections.

17.1. Index AnnotationsThe Index annotation allows you to define an index for a given class. The index may be on a singleclass attribute or multiple class attributes. (These are often referred to as simple or compoundindexes, respectively. However, V/JPA does not make that distinction.) The Index annotation issupplied with two annotation attributes, the name of the index and a list of the class attributes tobe indexed. The following shows an example, indexing two class attributes.

@Entity@Index(name = "CourseNumberDurationIndex",

119Versant JPA Developer's Guide

attributes = {"courseNumber", "duration"})public class Course {

@Idlong id;String courseTitle;int courseNumber;int duration;. . .

}

The value of the name attribute is a String and specifies the index name. The attributes attributevalue is a String array specifying the class attribute(s) to be indexed. The order of the class attributesis significant. The first attribute specified is the primary index.

17.2. Multiple IndexesIf youwant to specifymore than one index for a given class you canwrapmultiple Index annotationsin an Indexes annotation. The value of an Indexes annotation is an array of Index annotations.

@Entity@Indexes(

{@Index(name = "Index_1", attributes = {"field_1"}),@Index(name = "Index_2", attributes = {"field_2, field_3"})

})public class ClassWithMultipleIndexes {

@Idlong Id;String field_1;int field_2;long field_3;

}

Versant JPA Developer's Guide120

Multiple Indexes

17.3. Index Definition FileIndexes may also be defined using an index definition file. The following example shows such afile for the multiple indexes example described above.

<index-definitions version="1.0"><class name="com.example.ClassWithMultipleIndexes">

<index name="Index_1"><attribute name="field_1"/>

</index><index name="Index_2">

<attribute name="field_2"/><attribute name="field_3"/>

</index></class>

</index-definitions>

In order to associate a persistence unit with an index definition file, the propertyversant.indexesDefinitionFile is used.

<persistence-unit ...><class>...</class><properties>

<property ... /><property name="versant.indexesDefinitionFile"

value="META-INF/indexes.xml" /></properties>

</persistence-unit>

The index definition file may have any name that locates the file as a resource in the classpath.

17.4. Index InheritanceIn V/JPA sub-classes inherit the indexes of their super-classes by default. Assume you have thefollowing class definitions.

121Versant JPA Developer's Guide

Index Definition File

@Index("AaIndex", {"a"})public class A {

. . .int a;

}

public class B : extends A {. . .int b;

}

The class B also has an index on the inherited class attribute a.

You can disable automatic index inheritance by setting the property versant.inheritIndexes tofalse in the appropriate persistence unit (i.e., in the persistence.xml file).

<persistence-unit ...><class>...</class><properties>

<property ... /><property name="versant.inheritIndexes" value="false" />

</properties></persistence-unit>

17.5. Indexing Inherited AttributesAn index definition may contain class attributes from super-classes. For example, assume classesA with class attribute a and B with class attribute b.

public class A {. . .int a;

}

@Index("BbAaIndex", {"b", "a"})public class B : extends A {

. . .

Versant JPA Developer's Guide122

Indexing Inherited Attributes

int b;}

An index defined for class B can contain the member a from the parent class A.

If a given class does not contain the class attribute named in the index definition, the occurenceof the named class attribute from the nearest related class is used. For example, consider the nextclass hierarchy.

public class A {. . .int a;

}

public class B : extends A {. . .long a;int b;

}

@Index("CcBaIndex", {"c", "a"})public class C : extends B {

. . .int c;

}

In this case, the index for class C has the class attributes c from class C and a from class B.

17.6. Building Index Meta Data From AnnotationsTheV/JPA enhancer reads the Index and Indexes annotations for all classes that are to be enhanced.It builds up themetadata that is needed to create indexes. Thismetadata is appliedwhen you createan EntityManagerFactory instance.

The enhancer will throw an exception on the following conditions.

• The attribute annotated as @Id is in the indexed attribute set (exceptionIndexOnIdAttributeException)

123Versant JPA Developer's Guide

Building Index Meta Data From Annotations

• The attribute annotated as @Version is in the indexed attribute set (exceptionIndexOnVersionAttributeException)

• An attribute named in the indexed attribute set does not exist in the entity class (exceptionIndexedAttributeNotFoundException)

• The indexed attribute set is empty, i.e., no attributes to be indexed are specified (exceptionIndexOnEmptyAttributeSetException)

• The index name is null or empty (exception InvalidIndexNameException)

• The same name is used for more than one index definition (whether via annotations or in theindex definition file; exception NonUniqueIndexNameException)

Further checks are done by the server at schema comparison time.

17.7. Building Index Meta Data From an Index Definition FileIndex definition files are parsed only at runtime, at the creation of the EntityManagerFactoryinstance. Index definitions found at that point override index definitions of equally named indexesbuilt by the enhancer from annotations. The same checks for correctness are applied to indexesdefined in the index definition file(s) as for annotations.

17.8. Database Index Synchronization, Creation and EvolutionIndexes are defined in your application but exist in the database(s) your application connects to.You can control how your application synchronizes its index definitions with those in the database.

Synchronization

When you start your V/JPA application and connect to a database, the indexes the applicationdefines, either with annotations or in an index definition file, are normally compared with theindexes that already exist for the database. You can skip the index comparison and synchronizationof the application and database indexes by using the persistence unit propertyversant.skipIndexSynchronization. Setting the versant.skipIndexSynchronization property totrue (the default value for this property is false) will cause the index definitions in your client tobe ignored. This also prevents application-triggered index creation and evolution as described inthe next sections.

Versant JPA Developer's Guide124

Building Index Meta Data From an Index DefinitionFile

One aspect of synchronization is that is independent of the versant.skipIndexSynchronizationsetting is if the data model changes in such a way that an existing index is made invalid, e.g.,removing an indexed attribute (field). In such a case, the invalid index is always deleted in thedatabase. (This can occur if the application is using schema evolution. Refer to Chapter 10, SchemaEvolution pg. 71.)

Creation

By default, if indexes are defined in your application and the index does not already exist for thedatabase, the index will be created on the server. You can control this automatic creation with thepersistence unit property versant.indexDefine. The default value of this property is true. Settingthis property to false will prevent new index definitions from the application being created.

If your application defines an index that is not defined in the database and you have disabledautomatic index creation (versant.indexDefine is set to false) you will receive an exception. Youcan prevent index creation and avoid the exception by using the versant.skipIndexSynchronizationproperty, described above.

Evolution

The defininition of an index, that is the fields that are indexed and/or their order in the index, canevolve or change over time. In V/JPA, valid index evolution can be adding fields to an index, removingfields from an index or changing the sequence of the indexed fields. These evolutionary changesare automatically propagated to the database if the property versant.indexEvolve is set to true.

Index evolution is needed if the metadata defining the index (@Index/@Indexes annotations and/orin the indexes definition file) has changed and there is a same-named index in the database for thesame class but with different attributes or attribute sequence. In any given V/JPA Server database,only indexes that were, or potentially could have been, defined using the V/JPA binding can bechanged, i.e.,named, non-unique, B-tree indexes.

For example, assume that for a given class there is an index named Index_1 in the database onattributes member1 and member2. The index was created based on an older version of the class whichcontained an annotation that defined exactly the index on these two attributes. You now haveevolved the definition of the class with the index, still named Index_1, defined on attributes member1,member2 and member3. If index evolution is allowed (i.e., versant.indexEvolve is set to true), Index_1will be modified in the database to be in accord with the new version of the class.

125Versant JPA Developer's Guide

Database Index Synchronization, Creation andEvolution

If your application re-defines an index and you have disabled automatic index evolution(versant.indexEvolve is set to false) youwill receive an exception. You can prevent index evolutionand avoid the exception by using the versant.skipIndexSynchronization property, described above.

Versant JPA Developer's Guide126

Database Index Synchronization, Creation andEvolution

Chapter 18. Handling Large Query Results—CursorQueries

Versant JPA supports cursor queries. A cursor query returns the query result as a cursor iterator (aninstance of the V/JPA class CursorIterator) rather than a collection. As the name implies, theiterator acts as a cursor that points to a specific location in the query result. You can use a cursorquery wherever an iterator is appropriate for query results in your application.

Cursor queries are particularly useful if the query returns a very large number of entities. Whenusing a cursor query, the query itself is, in effect, executed in several batches of a configurableresult size. These intermediate results are transferred to the client as the cursor traverses theresults. For distributed databases, the cursor “walks” the results in a serial fashion. That is theresults from the first database in the list of databases followed by the results from the seconddatabase and so on. If you are specifying an ORDER BY condition the entire query result must becalculated on the server but the results are transferred to the client in the specified intermediatebatch size.

The Versant JPA class VersantQuery extends the standard JPA Query interface to provide the cursorquery functionality. Use the unwrap()method provided by the Query interface, i.e.,Query.unwrap(VersantQuery.class), to get the VersantQuery instance. To execute a cursor query,use the VersantQuerymethod getResultCursor(int batchSize). Cursor queries must be executedwithin a transaction.

em.getTransaction().begin();Query query =

em.createQuery("select these from ThatClass these");CursorIterator cursor = query.unwrap(VersantQuery.class).getResultCursor(1000);// use the cursor to read and operate on your results . . .em.getTransaction().commit();

The method returns a CursorIterator instance (not a collection). This iterator is the cursor for thequery results in the client application. The cursor iterator always begins at the first item in thequery result and is forward-only, i.e., you can only step forwards and not backwards in the result.The batchSize argument (1000 in the command above) specifies the size of the intermediate resultbatch that is transferred to the client. (The intermediate result size specified by thegetResultCursor() batchSize argument should not be confused with the batch size specified withthe versant.queryBatchSize property.)

The CursorIterator class

127Versant JPA Developer's Guide

The com.versant.jpa.CursorIterator class extends java.util.Iterator<T> andjava.lang.AutoCloseable. At the end of a transaction (commit/rollback), CursorIterator instancescreated in the context of the transaction are automatically closed and all resources associated withthe iterator are released. You can explicitly close the iterator with the CursorIterator.close()method. Attempting to use a closed iterator results in the exception IllegalStateException.

Versant JPA Developer's Guide128

Chapter 19. Application Monitoring

Sections• Logging

- XA Resource Logging• Monitoring Using JMX

- Enabling JMX- Accessing JMX MBeans- V/JPA MBean Data- The V/JPA Client MBeans- The V/JPA Server MBeans

• Session Name

There are times when you want to monitor your application while it is running. This can be togather performance statistics, activity logging, etc. This section introduces the information gatheringcapabilities in V/JPA.

19.1. LoggingVersant JPA uses the Simple Logging Facade for Java (SLF4J, www.slf4j.org) for all logging operations.Since SLF4J is just a facade, or abstraction, you can use any compatible logging framework to dothe actual logging. Following is a list of the compatible logging frameworks that are currentlyavailable.

• logback

• log4j

• java.util.logging

• Jakarta Commons Logging

• SLF4J Simple Logging

• SLF4J NOP (No Operation Logger)

129Versant JPA Developer's Guide

To enable logging, simply add the library for your framework of choice plus any framework-specificSLF4J binding and the configuration, if needed, to the application classpath. Logback, SLF4J SimpleLogging and SLF4J NOP do not need an extra binding. Bindings for the other frameworks can bedownloaded from www.slf4j.org.

If you want to use logback, for example, download the current archive from logback.qos.ch and addthe logback core and logback classic jar files to your classpath. The following is a minimalconfiguration which enables console logging for informational messages, warnings and errors. Toenable this configuration, create a file named logback.xml with this content in a top level folderin the classpath. (Complete documentation for logback can be found on their website atlogback.qos.ch/manual/index.html.)

<?xml version="1.0" encoding="UTF-8"?><configuration><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>

</encoder></appender><root level="info"><appender-ref ref="STDOUT" />

</root></configuration>

19.1.1. XA Resource Logging

The recoveryXA resource logs at the INFO level, which is enabled by default. The regular XA resourceslog activity at the FINER and FINEST levels. This will likely need to be explicitly enabled in the loggingconfiguration, as follows.

<logger category="com.versant.odbms"><level name="FINER"/>

</logger>

19.2. Monitoring Using JMXJava Management Extensions—JMX—provide a mechanism for monitoring resources in a Javaapplication. JMX defines the concept of anMBean (for managed bean) that represents a resourcerunning in the Java virtual machine. Versant JPA provides MBeans associated with the

Versant JPA Developer's Guide130

Monitoring Using JMX

EntityManagerFactory implementation (V/JPA Client MBeans) as well as MBeans associated withthe Server backend (V/JPA Server MBeans). These MBeans provide system data relating to thedatabase connection(s), system state for a V/JPA client application and server side statistics.

19.2.1. Enabling JMX

In order to view the information relating to the resources, the MBeans that provide the variousresource metrics need to be published, that is, made available from the entity manager factory.

To publish the MBeans belonging to an entity manager factory associated with a persistence unityou simply need to set the versant.jmx property to true for the desired persistence unit. Forexample, to enable JMX monitoring for the persistence unit named unit1, add the property to thepersistence unit configuration file (persistence.xml) as shown.

<persistence version="2.0"><persistence-unit name="unit1" transaction-type="RESOURCE_LOCAL">

. . .<properties><property name="versant.connectionURL" value="jpa_db1@localhost" /><property name="versant.jmx" value="true" />

</properties>. . .

</persistence-unit></persistence>

To enable the MBeans showing server-side statistics, set the property versant.jmxServer to true.These MBeans maintain their own connection to get statistical data from the server. If a usernameand password is needed to establish the connection, set versant.jmxServer.username andversant.jmxServer.password, respectively.

<persistence version="2.0"><persistence-unit name="unit1" transaction-type="RESOURCE_LOCAL">

. . .<properties><property name="versant.connectionURL" value="jpa_db1@localhost" /><property name="versant.jmxServer" value="true" /><property name="versant.jmxServer.username" value="versant_dba" /><property name="versant.jmxServer.password" value="########" />

</properties>

131Versant JPA Developer's Guide

Monitoring Using JMX

. . .</persistence-unit>

</persistence>

Note, that the MBeans showing server-side statistics are shared among multiple persistence units,so this bean is available as long as any persistence unit which has set versant.jmxServer=true isstill open.

19.2.2. Accessing JMX MBeans

You can use the jconsole tool on the same machine as your client application to view the MBeanmetrics. To view the metrics from a remote machine, enable external JMX monitoring via TCP byadding the following additional parameters to the command to start your application.

-Dcom.sun.management.jmxremote.port=9899-Dcom.sun.management.jmxremote.authenticate=false-Dcom.sun.management.jmxremote.ssl=false

Once you have started the jconsole connection, chooseMBeans. The following shows theV/JPAClientMBean hierarchy for persistence unit unit1 in a jconsole window. The V/JPA Client MBeans aredescribed in detail in Section 19.2.4, “The V/JPA Client MBeans” pg. 134. The V/JPA Server MBeansfor the server-side statistics are explained in Section 19.2.5, “The V/JPA Server MBeans” pg. 140.

Versant JPA Developer's Guide132

Monitoring Using JMX

There are a number of system management tools on the market that support the JMX standard andcan be used to monitor V/JPA.

19.2.3. V/JPA MBean Data

The data reported by the V/JPA MBeans are of two types, state data and statistical data.

The state data provide metrics representing the current state of objects in the system. This may bea static, configured value such as the port used for the database connection or a variable value suchas the number of currently used connections in a given connection pool. State data (with someexceptions) is read only.

133Versant JPA Developer's Guide

Monitoring Using JMX

Statistical data is accumulated data. These can be time-related values, such as time spent waitingfor connection allocations, or other performance-related information such as the total number ofremote procedure calls (RPCs) that have been executed. Accumulated statistical data is lost, i.e.,reset, in the event of a system reconnect.

19.2.4. The V/JPA Client MBeans

The root name for all V/JPA Client MBeans is com.versant.jpa[UnitName] where UnitName is thename of the persistence unit associated with the entity manager factory. If two or more entitymanager factories share a common persistence unit, a number is appended to the MBean name.For example, if you aremonitoring two entitymanager factories sharing the persistence unit unit1,the MBean names will show as com.versant.jpa[unit1] and com.versant.jpa[unit1]#2

The following sections summarize the available MBeans and their attributes.

19.2.4.1. Databases

The following MBeans provide information relating to the databases, database connections andconnection pools.

com.versant.jpa[UnitName]:type=Databases

This is a single MBean and is shared across all databases in the persistence unit.

This MBean has the following attribute.

Versant JPA Developer's Guide134

Monitoring Using JMX

Data TypeDescriptionAttributejava.lang.BooleanThis attribute is writable and may be

set during runtime. If enabled, eachdumpAllocationStackIfPoolIsFull

time a connection is allocated, anallocation stacktrace is calculated andheld in memory. This has someperformance impact.

If a connection request cannoteventually be satisfied because thepool is full, all stacktraces aredumped to System.err. Note thatstack traces may not be available forconnections that are allocated beforethis property is enabled.

com.versant.jpa[UnitName]:type=Databases,category=DatabaseName

There is an instance of this MBean for each database defined in the persistence unit. Thedatabase is indicated by the DatabaseName category value (in the formdatabaseName@serverName).

This MBean has the following attribute.

Data TypeDescriptionAttributejava.lang.IntegerThis is the connection port on the

server for the named database.ServerPort

135Versant JPA Developer's Guide

Monitoring Using JMX

com.versant.jpa[UnitName]:type=Databases,category=DatabaseName,name=ConnectionPool

There is an instance of this MBean for each database, indicated by the DatabaseName category.This returns information about the database connection pool. Unless noted, these are allaccumulating, statistical values and are reset when a system reconnect event occurs (refer toSection 19.2.3, “V/JPA MBean Data” pg. 133).

This MBean has the following attributes.

Data TypeDescriptionAttributejava.lang.LongThis is the number of failed attempts

to obtain a connection from the pool.This includes timeouts.

AllocationFailures

java.lang.LongThe maximum wait-time for aconnection to be allocated from theconnection pool.

AllocationMaxWaitTime

java.lang.LongThe number of times a connectionfailed because of a connection

AllocationTimeouts

timeout. This number is included inthe total allocation failures(AllocationFailures).

java.lang.LongThe total number of failedconnections to server. This number

ConnectionFailures

does not increment for each retry(refer to ConnectionRetries).

java.lang.LongThe total number of invalidatedconnections. A connection can be

ConnectionInvalidations

Versant JPA Developer's Guide136

Monitoring Using JMX

Data TypeDescriptionAttributeinvalidated as a result of a reconnectevent, for example.

java.lang.LongThe total number of retry attemptsmade to establish connections to the

ConnectionRetries

server. This number is not includedin the number of connection failures(refer to ConnectionFailures, above).

java.lang.IntegerThe total number of connectionscurrently in use. (This is a state data

ConnectionsInUse

value. Refer to Section 19.2.3, “V/JPAMBean Data” pg. 133.)

java.lang.IntegerThis is themaximumconnectionpoolsize as configured in the persistence

MaxSize

unit. Refer toversant.connectionPoolSize pg. 6for more information. (This is a statedata value. Refer to Section 19.2.3,“V/JPA MBean Data” pg. 133.)

java.lang.IntegerThe number of currently allocatedconnections. (This is a state data

Size

value. Refer to Section 19.2.3, “V/JPAMBean Data” pg. 133.)

java.lang.LongThis metric reports the total timespentwaiting for the connection poolto allocate connections.

AllocationTotalWaitTime

java.lang.LongThis is the total number of allocationsmade from the connection pool.

TotalAllocations

137Versant JPA Developer's Guide

Monitoring Using JMX

com.versant.jpa[UnitName]:type=Databases,category=DatabaseName,name=NetworkIO

There is an instance of this MBean for each database, indicated by the DatabaseName category.This returns information about the network traffic associated with the database. These are allaccumulating, statistical values and are reset when a system reconnect event occurs (refer toSection 19.2.3, “V/JPA MBean Data” pg. 133).

This MBean has the following attributes.

Data TypeDescriptionAttributejava.lang.LongThe total number of bytes received

from the named database.BytesReceived

java.lang.LongThe total number of bytes sent to thenamed database.

BytesSent

java.lang.LongThe total number of objects receivedfrom the named database.

ObjectsReceived

java.lang.LongThe total number of objects sent tothe named database.

ObjectsSent

java.lang.LongThe total number of remoteprocedure calls (RPCs) executed bythe server for the named database.

RPCCount

19.2.4.2. Entity Manager Factory

This single MBean reports the number of active entity managers, i.e., EntityManager instances,derived from the entity manager factory.

Versant JPA Developer's Guide138

Monitoring Using JMX

com.versant.jpa[UnitName]:type=EntityManagerFactory

This MBean has the following attribute.

Data TypeDescriptionAttributejava.lang.IntegerThe number of entity managers

(EntityManager instances) currentlyActiveEntityManagers

active for the entitymanager factory.This is a state data value. Refer toSection 19.2.3, “V/JPA MBeanData” pg. 133.

19.2.4.3. Cache

The CacheMBean provides information about the entity manager factory interaction with thesecond-level cache. These are all accumulating, statistical values and are reset when a systemreconnect event occurs (refer to Section 19.2.3, “V/JPA MBean Data” pg. 133).

This MBean is only published if you have enabled a second-level cache (refer to Chapter 6,Second-level Cache pg. 51).

Your second-level cache implementation may also provide JMX MBeans for additional cachemonitoring.

com.versant.jpa[UnitName]:type=Cache

This MBean has the following attribute.

Data TypeDescriptionAttributejava.lang.LongThis performance metric is the

number of additional remoteRPCsAvoided

procedure calls (RPCs) that wouldhave been necessary without thecache.

java.lang.LongThis reports the total number ofobjects that were forcibly read from

CacheBypasses

the database, even though a copyexisted in the cache.

139Versant JPA Developer's Guide

Monitoring Using JMX

Data TypeDescriptionAttributejava.lang.LongThe total number of object read

operations from the cache.CacheHits

java.lang.LongThe total number of object readoperations from the database.

CacheMisses

java.lang.LongRelated to CacheBypasses, this is thenumber of RPCs needed to satisfyforced reads.

RPCsEnforced

java.lang.LongThis is the total number of RPCsperformed to read objects from the

RPCsPerformed

database. (This does not include theRPCsEnfocrced value.)

19.2.5. The V/JPA Server MBeans

The server side statistics are provided via two beans, as described below.

com.versant.jpa:type=Databases,category=DatabaseName,sub=AvailableStatistics

This MBean contains a fixed set of writeable boolean-typed attributes, each representing anindividual statistic which can be turned on or off.

Each of the statistics provides a description, for further information see Appendix A, ServerStatistics Reference pg. 193

Versant JPA Developer's Guide140

Monitoring Using JMX

com.versant.jpa:type=Databases,category=DatabaseName,sub=EnabledStatistics

This contains read-only attributes of type Long for exactly the enabled statistics. I.e. enablingor disabling a statistic via the first bean changes the number of attributes of the second bean.

Each of the statistics provides a description, for further information see Appendix A, ServerStatistics Reference pg. 193

Note, that enabling statistics can have an impact on the system performance.

Enabling Server statistics has an impact on the database server backend while enabling Clientstatistics impacts only the EntityManagerFactory running on the specific client.

19.3. Session NameA session name provides an identity in the Versant JPA Server for the database connections andtransactions created by the Versant JPA clients. The session name is set with theversant.sessionName property in the persistence.xml persistence unit file or in a property mapargument in the Persistence.createEntityManagerFactory(map) call. If the versant.sessionNameproperty is not specified, the default is V/JPA. You can use any string value for the session name.The maximum length of the session name is 63 characters.

The session name specified in this way is associated with the entity manager factory. You can alsoset the session name for a specific EntityManager instance usingVersantEntityManager.setSessionName(). Thiswill change the sessionname for existing connectionsas well as future connections associated with the entity manager. You can get the session name

141Versant JPA Developer's Guide

Session Name

for the entity manager with VersantEntityManager.getSessionName(). For transactions, the nameis set during creation of the transaction and cannot be changed while the transaction is running.

The session name identity is useful whenmonitoring theV/JPA application. It is usedwhen reportingthe database connections using the Versant JPA Server command line utility vstats, e.g.,

vstats -database dbname -connections

Transactions can be viewed with Versant JPA Server dbtool command line utility

dbtool -trans -info dbname

Versant JPA Developer's Guide142

Session Name

Chapter 20. Automatic Client Reconnect

Sections• Reconnect Properties• Exception Handling—JSE Applications• Exception Handling—JEE Containers• Reconnect Listener

In a default Versant JPA Server configuration, when a client detects a loss of connection to theserver, this leads to a non-recoverable exception in the client and the entity manager factory andassociated entity managers become unusable. To handle such connection loss, the client must bewritten in such a way that it creates a new EntityManagerFactory instance, if possible, or the clientneeds to be restarted.

If you are using a high-availability setup, for example a Veritas Cluster, when a node becomesunavailable, a replacement node will take over and make itself available via the same IP address.This failover will require that Versant JPA Server run any necessary recovery procedures whichmaytake some time depending on the database configuration. But the system will come back online.For such scenarios, Versant JPA can be configured to perform an automatic reconnect. When thisfeature is enabled the client can continue to work with the current EntityManagerFactory andEntityManager instances. However, any active transactions are lost. The client will have to redothe current transaction.

Automatic reconnect is configured in the persistence unit (persistence.xml file) for the applicationand can also be enabled for a specific entitymanager factory or entitymanager. The auto-reconnectproperties are described in Section 20.1, “Reconnect Properties” pg. 144.

How your application interacts with auto-reconnect is related to the the environment in which itruns, i.e., as a stand-alone client application (a Java Standard Edition, JSE environemnt) or withinan application server or enterprise environment (Java Enterprise Edition, JEE). This interaction isdescribed in Section 20.2, “Exception Handling—JSE Applications” pg. 144 and Section 20.3,“Exception Handling—JEE Containers” pg. 146, respectively.

V/JPA also provides you with a listener to monitor the reconnect operation. This is described inSection 20.4, “Reconnect Listener” pg. 147, below.

143Versant JPA Developer's Guide

20.1. Reconnect PropertiesThere are two properties to configure the automatic reconnect behavior.

Specifies the number of reconnect attempts. Ifversant.reconnectCount is set to 0 (zero), no reconnect attempts

versant.reconnectCount

are made. This is the default setting, i.e., automatic reconnect is,by default, disabled.

Specifies the time, in milliseconds, between reconnect attempts.If versant.reconnectCount is 0, this property is ignored.

versant.reconnectWait

<persistence version="2.0"><persistence-unit name="CountWait" transaction-type="RESOURCE_LOCAL">. . .<properties><property name="versant.reconnectCount" value="10" /><property name="versant.reconnectWait" value="100" />

</properties></persistence-unit>

</persistence>

The combination of versant.reconnectCount and versant.reconnectWait establishes a reconnecttime frame. For example, a count of 10 with a wait time of 100 results in time frame of 1000milliseconds to re-establish the server connection.

If automatic reconnect is enabled and a connection loss is signalled, the current transaction isautomatically rolled back. The client should not explicitly commit or rollback the transaction. Fromthe client perspective, this automatic rollback is identical to a user triggered rollback, that is, allentity instances get detached. In most cases, you will start the transaction over by callingTransaction.begin() and the client will attempt to re-establish connection. Your applicationmustfetch new managed instances to redo the interrupted task. (When outside of an active JPAtransaction, automatic reconnect is performed transparently.)

20.2. Exception Handling—JSE ApplicationsWhen the connection is lost, the client is signalled via the exception ConnectionLostException.This exception provides themethod getStatus() for determining the reconnect status. Themethodreturns an enumerated value of type ReconnectFailStatus enumeration.

Versant JPA Developer's Guide144

Reconnect Properties

Table 20.1. ReconnectFailStatus Enumeration Values

MeaningValueA connection loss was detected. The current transaction isautomatically rolled back. The next attempt to open a connection

CanBeRetried

from this entity manager, that is, when you callTransaction.begin(), will use the configured values forreconnectCount and reconnectWait to attempt a reconnect. If theserver is available within the configured time frame, theconnection effectively succeeds.

A connection loss was detected. The current transaction isautomatically rolled back. Automatic reconnect is enabled but a

RetryFailed

connection to the serverwas not establishedwithin the configuredtime frame. The client can either treat this as a permanent failureor can try the reconnect again with another call toTransaction.begin().

A connection loss was detected. Automatic reconnect is notenabled—versant.reconnectCount is set to 0. The current

RetryDisabled

EntityManagerFactory and EntityManager instances are no longerusable. The applicationmay attempt to continue by creating newfactory/manager instances.

The following example demonstrates howyoumight handle the ConnectionLostException exceptionto use automatic reconnect.

boolean doTxnRetry;do{try{em.currentTransaction.begin();. . .em.currentTransaction.commit();doTxnRetry = false;

}catch( ConnectionLostException e ){if ( e.getStatus() == ConnectionLostException.CanBeRetried ){doTxnRetry = true;

}else{doTxnRetry = false;

145Versant JPA Developer's Guide

Exception Handling—JSE Applications

}}

} while ( doTxnRetry );

20.3. Exception Handling—JEE ContainersWhen running inside a JEE container, you will not have the same level of control over the reconnectprocess as described above. Depending on the point in a transaction when the connection is lost,reusing existing resources following a reconnect may not be possible. The following describes thereconnect behavior based on whether connection is lost at a transaction boundary or within atransaction.

Transaction boundary

If the connection is lost during a transaction boundary operation (begin/rollback/commit) theclient will receive the exception EJBTransactionRolledbackException. As the name implies,this exception indicates that the transaction is marked for rollback. The client-side beanreference will still be usable. Implicitly starting a new transaction by invoking a transactionalbusiness method will initiate the reconnect.

Within a transaction

If the connection is interrupted during an in-transaction activity (query, find, etc.) the defaultbehavior is that the client will receive an EJBException system exception wrapping theConnectionLostException exception. In this case, the application will have to reacquire a beanreference, i.e., perform a fresh lookup and continue to work with the new client-side beanreference.

For the client to continue to use the existing bean reference following a reconnect, you candeclare the ConnectionLostException as an application exception and that it marks thetransaction for rollback. This results in the client receiving a simple ConnectionLostExceptionwhen a connection is lost and the current bean reference remains valid. The transaction ismarked for rollback and beginning a new transaction will trigger the reconnect, as above. Thefollowing shows how to set up ConnectionLostException as an application exception in the EJBdeployment descriptor file.

<application-exception><exception-class>com.versant.jpa.core.exceptions.ConnectionLostException

Versant JPA Developer's Guide146

Exception Handling—JEE Containers

</exception-class><rollback>true</rollback><inherited>false</inherited>

</application-exception>

20.4. Reconnect ListenerA reconnect listener allows you to perform your own operations when a reconnect is triggered. Youcan use the listener to send a notification or create entries in an application log, for example. Thelistener responds before the reconnect is attempted and again when the reconnect has completed.For the reconnect end notification, you can implement different behavior for a successful or failedreconnect.

You create a reconnect listener by implementing the ReconnectListener interface and registeringyour implementation in the persistence unit or in the appropriate VersantEntityManagerFactoryinstance. Reconnect listeners are called only if automatic reconnect is active (refer to Section 20.1,“Reconnect Properties” pg. 144, above).

The ReconnectListener interface

Your reconnect listeners must implement the ReconnectListener interface.

public interface ReconnectListener {void onBeforeReconnect( ReconnectEvent event );void onSuccessfulReconnect( ReconnectEvent event );void onFailedReconnect( ReconnectEvent event );

}

There are threemethods and their function is clear from their names. The ReconnectEvent instancepassed in the event argument contains a Database instance representing the lost database. TheReconnectEvent class has a single method, getDatabase(), that can be called in your listenerimplementations to get the Database instance.

Registering your listener

In the persistence unit

147Versant JPA Developer's Guide

Reconnect Listener

A reconnect listener class is registered in the persistence unit (persistence.xml file) with theversant.reconnectListener vendor-specific property. The following example shows settingauto-reconnect (a positive value for versant.reconnectCount) and registering the listener classcom.versant.jpa.j2ee.jboss.beans.JBossReconnectListener.

<persistence-unit name="jboss_reconnect_listener" transaction-type="JTA">. . .<properties><property name="versant.connectionURL" value="db1@localhost" /><property name="versant.reconnectCount" value="10" /><property name="versant.reconnectListener"

value="com.versant.jpa.j2ee.jboss.beans.JBossReconnectListener" /></properties>

</persistence-unit>

Only one listener class may be registered in the persistence unit.

In the entity manager factory

You can register and unregister one or more reconnect listener instances in the entity managerfactory. The VersantEntityManagerFactory class provides themethods registerReconnectListener(ReconnectListener reconnectListener ) and unregisterReconnectListener( ReconnectListenerreconnectListener ), for registering and unregistering your listener instance(s).

EntityManagerFactory emf = Persistence.createEntityManagerFactory( . . . );MyReconnectListener myListener = new MyReconnectListener();(VersantEntityManagerFactory) emf.registerReconnectListener( myListener );. . .(VersantEntityManagerFactory) emf.unregisterReconnectListener( myListener );

Multiple listeners can be configured using these methods in addition to any listener registered inthe persistence unit. That is, if a listener is registered in the persistence unit and another in theVersantEntityManagerFactory, both listeners will be active.

JEE

When using a reconnect listener in a JEE environment, only persistence unit registration is supported,i.e., you can only specify the listener in the persistence unit, not in the entity manager factory. Also,ensure that the listener class is bundled with the entity classes so it can be found by the classloader.

Versant JPA Developer's Guide148

Reconnect Listener

Chapter 21. The Generic API

The generic API provides a freestanding mechanism for accessing the content of a V/JPA databasewithout the need of having the JPA entity classes available. This allows you to write tools that canbrowse and modify the database content.

The pre-defined internal system classes are not visible through the V/JPA Generic API.

Enabling generic access

To enable generic access for a given persistence unit, add the following property to the unit definitionin the persistence.xml file.

persistence.xml

<property name="versant.genericAccess" value="true" />

Each V/JPA class in the database is represented by an instance ofcom.versant.jpa.generic.DatabaseClass. Any generic instance is an instance ofcom.versant.jpa.generic.DatabaseObject.

To determine the type of a DatabaseObject instance use the method getType() which returns thecorresponding instance of DatabaseClass.

The DatabaseClass class defines a number of static methods for looking up instances ofDatabaseClass, for example, forName(String className, EntityManagerFactory scope). TheEntityManagerFactory instancemust be supplied in order to set the scope in which you are lookingfor the class.

Working with generic instances

A simple example application using the V/JPA Generic API is provided in the vjpa2/jpa_generic_apidirectory in your V/JPA installation. To use the example, read the instructions in the README.txtfile in the example directory.

149Versant JPA Developer's Guide

All entities returned through any JPA API or simply via navigation are of type DatabaseObject. Ifyou need to create a new instance of a particular class, you can call newInstance() on theDatabaseClass object.

Values of an instance field are obtained or modified with the DatabaseField get and setmethods.

DatabaseObject dbObj = . . .DatabaseField field = dbObj.getType().getDeclaredField(fieldname);Object o = field.get(dbObj);field.set(dbObj, value);

To obtain a list of available fields, themethod getDeclaredFields() can be called on a DatabaseClassinstance. This returns the declared, but not the inherited fields, of this class. The fields arerepresented as instances of com.versant.jpa.generic.DatabaseField, and getType() returns thedeclared type of this field, which can be a java.lang.Class instance (for primitive fields) or acom.versant.jpa.generic.DatabaseClass instance (for a single reference to another persistentclass). To get the full type information, the method getTypeName() can be used. For example, ifgetType() returned List.class, then getTypeName() also contains the generic arguments of thisList (e.g., java.lang.List<PersClass>).

Type mappings

For field types such as primitives (int, double, etc.), wrapper types (Integer, Double) and primitivearrays, the database representationmatches the type. In these cases the generic API can return thetype exactly. For Java and other class types,more than one typemay bemapped to the same databasetype. For such types, the generic API does not have the information available to determine whatthe original declared type was in the Java entity class and can only return the common type asstored in the database. The datatypes you can expect from the generic API are summarized asfollows.

For the following, non-collection field types, the generic API provides the type exactly as originallydeclared.

• Primitives:

floatintbytebooleandoublelongshortchar

• Arrays of primitives:

float[]int[]byte[]boolean[]double[]long[]short[]char[]

Versant JPA Developer's Guide150

• Wrappers (java.lang):

FloatIntegerByteBooleanDoubleLongShortCharacter

• Single typed references to a persistent object (e.g., PersClass myReference)

• java.lang.String

• java.sql.Timestamp (refer to Date/Time, below)

The following describes the type catagories which have a common represention in the database.When using the V/JPA generic API the common type is returned.

• Date/Time

Represented as java.sql.Timestamp (this type offers the highest precision). Also applies if thedate type is a generic argument of any collection or map. Affects the following types:

java.util.Datejava.sql.Datejava.sql.Timejava.sql.Timestamp (the common type)

• Interface

Any interface is represented as java.lang.Object. This also applies if the interface type is ageneric argument of any collection or map.

• Array

Any array type, except an array of a primitive type, is represented as an appropriately typedjava.util.List.

• Collection

Any supported Collection type is represented as an appropriately typed java.util.List.

• Map

Any supported Map type is represented as an appropriately typed java.util.Map.

151Versant JPA Developer's Guide

Notes for Collection and Map

Sets are represented as List

Using the generic API, you can break the Set contract by inserting duplicates. Duplicates will beremoved when you next access the set with the non-generic API, however, it can not be guaranteedwhich of the duplicate objects contained in the set will be removed.

hashCode() and equals()

The declared type might rely on the hashCode() and/or equals() implementation of the entityclass. The DatabaseObject instance cannot reflect any such user implemented behavior. Thus, thecontract of the declared field might be violated.

Null collection elements

Note, that some collection/map types do not support adding null elements. Using the generic API,these constraints cannot be enforced. Adding a null element to such a collection may result in aninconsistent state.

Generic Queries

The generic API classes do not show the ID field (@Id) in the the list of declared fields. (You canuse the DatabaseObject.getLoid()method to get this value for a particular object.) Since the IDfield is not directly available from the generic API you are not able to formulate a query with yourID field name in the expression. In order to allow a query to use the ID field, V/JPA provides anartificial field, selfoid, for use in a query expression.

select p.selfoid from Person p

(Note that if you have declared a field with the name selfoid in your class, that field will be used.)

Cascade and eager load settings

The original cascade and eager load settings are not known to the generic API, so they will havethe field type dependent default values.

Versant JPA Developer's Guide152

The Generic API and Distributed Databases

The generic API will only work with distributed databases if the schema information for eachdatabase is the same. If the schemas are not found to be equal, an exception will be thrown whenopening the EntityManagerFactory instance. Schemas are considered equal if they have the sameset of classes with the same inheritance hierarchy. Additionally, for each class, the lists of fieldsare compared and need to be equal though the order of the fields in the different database schemasneed not be the same. Classes not defined byV/JPA (such as, e.g., internal system classes) and indexdefinitions are ignored when comparing the schemas.

153Versant JPA Developer's Guide

Versant JPA Developer's Guide154

Part II. Versant JPA and the JPASpecification

Chapters• Restrictions• Versant JPA Implementations• Currently Supported Features• JPA Public API Support

Versant JPA is an implementation of the Java Persistence API—as specified in JSR-000317 Java™Persistence 2.0 of the Java Community Process Program—for Versant JPA Server.

This describes the JPA features that are currently supported in Versant JPA and the areas whereV/JPA differs with regard to the official JPA specification.

The official specification for JSR-000317 Java™ Persistence 2.0 can be downloaded athttp://jcp.org/aboutJava/communityprocess/final/jsr317/index.html

In addition, though not strictly related to JPA, the first section describes some restrictions tostandard Java data types that are imposed by the storage types used by the Versant JPA Serverdatabase.

Chapter 22. Restrictions

Sections• Annotations• Data Types• Queries

22.1. AnnotationsThe annotations @Embedded, @EmbeddedId and @Embeddable are not supported in Versant JPA. Usingany of these annotations will result in an UnsupportedAnnotationException exception. (Supportfor @Embedded and @Embeddable is planned for a future release.)

The annotation @ElementCollection is only supported for collections of primitive types. (This is aconsequence of @Embeddable being not yet supported.) Using @ElementCollection for collectionsof entities (not supported by the JPA specification) will result in an exception.

22.2. Data TypesYour Java data types are mapped to appropriate storage types in the Versant JPA Server database.This is invisible to your V/JPA application, however, this mapping imposes some restrictions onthe value ranges for certain types. The following describes these restrictions for the Java data typesused in your application.

Data Type Range Restrictions in Versant JPA

charCharacter

In the Versant JPA Server database these types are stored as unsigned 16-bit values. Charactersoutside of the 16-bit plane are a rare case but must be avoided.

157Versant JPA Developer's Guide

java.util.Date

The java.util.Date class is based on the number ofmilliseconds since January 1, 1970, 00:00:00GMT (the “epoch”). It uses 37 bits for the date and 27 bits for the time (counted frommidnight).The Versant JPA Server database storage type represents the time to nanosecond resolution,requiring 12 additional bits for the time. These bits are “borrowed” from the date representationresulting in only 25 bits available for the date. Therefore, the maximum date value for V/JPAis April 11, 2262, 23:47:16 GMT.

java.sql.Date

The java.sql.Date has no time component but is otherwise is the same as java.util.Date anduses the same database storage type. This means that java.sql.Date also has a maximum dateof April 11, 2262.

java.sql.Timestamp

The java.sql.Timestamp type is essentially the same as java.util.Date, representing bothdata and time, and has an additional internal field for higher time resolution. In the VersantJPAServer database, java.sql.Timestampuses the same internal storage type as java.util.Date.The Timestamp type has full time resolution in V/JPA but the same date restriction as forjava.util.Date resulting in a maximum value of April 11, 2262, 23:47:16.854775807.

22.3. QueriesQuery projections of Java wrapper type (Integer, Float, etc.) entity class attributes with null valuesis currently not supported. Rather than null, the query will return the value as 0 (zero).

Versant JPA Developer's Guide158

Queries

Chapter 23. Versant JPA Implementations

Sections• Primary Keys and Object Identifiers• Mapping• Entity Graphs

- Implementation- Clarification

• Normalization• Flush Operations• Entity Class Enhancement• Cascading Persistence• The Entity Manager find() Method• Query Support• Object Cloning• Entity Lifecycle Listeners• Locking and Concurrency Control• Mapped Superclasses• Serializable Fields• XAResource Implementation

This section provides you with important information about the Versant JPA implementation ofcertain points of the JPA specification.

23.1. Primary Keys and Object IdentifiersIn a JPA entity class there must be a field or property that is designated as the primary key. This isindicated by the @Id attribute.

@Enitityclass Person {

. . .@Idlong id;

159Versant JPA Developer's Guide

. . .}

The primary key uniquely identifies the entity object in the database. In an object-oriented databasethis unique identifier is referred to as the object identity. The object indentity in a V/JPA Serverdatabase is represented by a 64-bit number and the value is assigned by the V/JPA Server server.What this means for Versant JPA is that only types long or java.lang.Long are permitted for the@Id attribute. Prior to the object being made persistent the value of the ID field or property is zero(0L). The value is assignedwhen performing the persist operation and/or persist cascade operationsthat take place during a flush.

Since this object identifier is assigned by V/JPA Server you may not use key generators or othermechanisms to set the ID and attempting to write to the field or property will result in a runtimeerror. Read access to the ID field is allowed.

This is a deviation from the JPA specification.

23.2. MappingBecause Versant JPA Server stores your objects with a similar data model in the database and inmemory there is no need to map between those two models. In fact, Versant JPA will ignore anymapping information you provide. This is true for mapping of attributes as well as for mapping ofthe inheritance structure. Keep it simple and just don’t specify anything mapping-related for theattributes in your class. It will just work.

This is a deviation from the JPA specification.

23.3. Entity GraphsAn entity graph can be used in find and query operations to optimize the load behavior of objectnetworks. V/JPA supports entity graphs as defined in the JPA 2.1 specification. (Entity graphs inV/JPA are briefly discussed in Chapter 14, Fetch Strategies pg. 103. For a detailed discussion of entitygraphs, refer to the JPA specification or any of the many available JPA resources.)

Versant JPA Developer's Guide160

Mapping

23.3.1. Implementation

Entity Graphs are defined in JPA 2.1. In oder to remain a JPA 2.0 compliant product, V/JPA supportsentity graphs as follows.

XML Metadata

When specifying the entity graph in the XML metadata, use the specified JPA 2.1 metadatasyntax. V/JPA extends the validation of XML files to support JPA 2.1 entity graph syntax.

Interfaces

The JPA 2.1 interfaces are not available to your V/JPA 2.0-compliant application. Use therespective V/JPA interface as given in the following table.

V/JPA InterfaceJPA 2.1 InterfaceVersantEntityGraphEntityGraph

VersantSubgraphSubgraph

VersantAttributeNodeAttributeNode

Annotations

The JPA 2.1 annotations are not available. V/JPA provides semantically identical annotationsin the com.versant.jpa.annotations package. Use the respective V/JPA annotation name asgiven in the following table.

V/JPA AnnotationJPA 2.1 AnnotationNamedVersantEntityGraphNamedEntityGraph

NamedVersantEntityGraphsNamedEntityGraphs

NamedVersantSubgraphNamedSubgraph

NamedVersantAttributeNodeNamedAttributeNode

Entity Manager and Manager Factory Methods

The JPA 2.1 methods for EntityManager and EntityManagerFactory are provided throughVersantEntityManager and VersantEntityManagerFactory, respectively. TheVersantEntityManager instance can be accessed by usingEntityManager.unwrap(VersantEntityManager.class). The VersantEntityManagerFactory

161Versant JPA Developer's Guide

Entity Graphs

instance can be accessed by casting the EntityManagerFactory instance (applies only to SEenvironments).

23.3.2. Clarification

The following points clarify the V/JPA entity graph implementation with respect to the JPAspecification.

• The entity graph passed to VersantEntityManagerFactorymethod addNamedEntityGraph()mustbe a graph defined in the same EntityManagerFactory context.

• Multiple subgraph definitions (for the same type) within one entity graph definition are permittedand the values are combined if not conflicting.

• A subgraph reference which can not be resolved will be handled as a reference to an emptysubgraph (and not raise an error).

• Subgraph definitions which are not referenced are ignored.

• Multiple attributes referencing the same sub-graph is allowed. The semantic is that a copy ofthat sub-graph is created, per reference, in the entity graph.

• Since objects are always completely loaded (or not loaded at all), it is not neccessary to includeany fields for the entity graph which are not (or do not contain) references to other entities.

• All eager fetching or load graph fetching or fetch graph fetching stops at entities which are alreadyloaded.

23.4. NormalizationThe major differences between an object storage model and a relational storage model are howrelationships and inheritance are handled. The storage model for an object-oriented database is,unsurprisingly, pretty similar to that of the datamodel of an object-oriented programming languagesuch as Java or C++.

The types of attributes of a class in such a database can be categorized as follows.

• Basic types such as int or float (java.lang.String is also treated as a basic type)

• References to other persistent objects (conceptually equivalent to a foreign key)

Versant JPA Developer's Guide162

Normalization

• Collections of basic types or references

So, data-model-wise, this looks pretty similar to a table which has some collection-valued columns.In relational lingo, this would be a Non-First-Normal-Form (NFNF) database, because apparentlythis contradicts the first NF of the relational data model. However object-oriented models simplydon’t need that, so relationships are stored directly in the owning object. Thus, it is unnecessaryto specify anything regarding the mapping of the relationship. It is not even necessary to use@OneToOne, @OneToMany, @ManyToMany or @ManyToOne, unless you want to specify some behavior forcascading operations.

This is a deviation from the JPA specification.

Because the data model in the Versant JPA database is the same as in Java, bi-directional relationshipsare stored on both sides of the relationship. As there is no owner of a bi-directional relationship,if you change one side of the relationship you are responsible for changing the relationship in theother side. This is also required by the JPA specification.

23.5. Flush OperationsWhen performing a flush operation, V/JPAwill only consider dirty entities in the persistence contextas candidates for the flush. Once the flush is complete, the entities that were flushed are markedas “clean”, i.e., they are no longer dirty. An important aspect of this implementation is that if thereare no dirty entities, a flush operation in V/JPA has no effect and no entities are evaluated. Thishas significant performance benefits. Since V/JPA need not keep a reference to clean entities, theseentities are available for garbage collection (provided your application also has no references). Thisallows for efficient memory use when dealing with large numbers of entities in a transaction andhas particular value when using automatic flushing (refer to Chapter 7, Automatic Flushing pg. 57).

However, there is a situation where this may be considered to be a deviation from strict compliancewith the JPA specification. Consider the following example. In your application you have two objectinstances, ann and ben, and ann has a reference to ben. If you explicitly persist ann (em.persist(ann))both ann and ben are now managed. Following a flush operation, you detach ben. According to theJPA specification, if you perform another flush, the entity manager should detect that ann nowreferences a detached entity and throw an exception.

Person ann = new Person();Person ben = new Person();ann.setChild( ben );em.persist( ann ); // ann and ben are now managed objects

163Versant JPA Developer's Guide

Flush Operations

em.flush(); // ann and ben are flushed to the database// and they are no longer marked as dirty

em.detach( ben ); // ben is no longer managedem.flush(); // no exception thrown

Following the first flush, the entities are no longer marked as dirty. V/JPA will not consider theentities when performing the second flush and not detect that entity ann now references anunmanaged entity, i.e., ben. This is not strictly conformant to the JPA specification but this behaviorwas chosen in order optimize overall performance. Had the entity ann been modified, or otherwisemarked as dirty, sometime between the detach and second flush, the behavior would conform tothe specification.

. . .em.persist( ann ); // ann and ben are now managed objectsem.flush(); // ann and ben are flushed to the databaseem.detach( ben ); // ben is no longer managedann.setSomething(); // ann is now marked as dirtyem.flush(); // EntityExistsException is thrown

This time, the entity ann is evaluated by V/JPA and the second flush does result in the exceptionEntityExistsException indicating that the reference to ben is invalid.

This is a deviation from the JPA specification.

23.6. Entity Class EnhancementVersant JPA uses a so-called enhancer to modify your @Entity classes to make them persistencecapable. This enhancement can be triggered in different ways—at runtime by specifying a JVMargument to call the Versant JPA enhancement agent or at build-time using an ant task or Javaexecutable. Enhancement allows persisting and retrieving entities in themost efficient way. (Referto Chapter 3, Enhancing Your Entity Classes pg. 35 for information.)

This is not a deviation from the JPA specification and is a permitted implementation strategy.

Versant JPA Developer's Guide164

Entity Class Enhancement

23.7. Cascading PersistenceAccording to the JPA specification, if you have a persistent object that references an object thathas not explicitly been made persistent, the referenced object may be made persistent usingcascading persistence. The cascading persist behavior may be specified for a given reference fieldusing the PERSIST cascading operation. The JPA specification also allows for the cascading persistbehavior to be applied in all cases and to all reachable objects in an object network using thecascade-persist element in the persistence unit. This latter behavior is also known aspersistence-by-reachability. Following the JPA specification, failure to use some form of cascadingpersist will result in an exception if any object in a persistent network has not been explicitly madepersistent.

V/JPA and persistence-by-reachability

InV/JPA, the global cascading persist behavior, i.e., persistence-by-reachability, is the only supportedbehavior. Versant JPA enforces the intuitive persistence-by-reachability behavior as a key designconcept. This has been done to keep the implementation fast and maintainable, especially wheninteractions with automatic flushing take place. Persistence-by-reachability is really useful and,from the point-of-view of V/JPA, is really the only way an object-oriented storage mechanismshould work.

This is a deviation from the JPA specification.

23.8. The Entity Manager find() MethodThe Versant JPA implementation of the find()method can be used to return an individual entityor a list of entities by specifying the enity ID or a list of IDs.

Employee emp = em.find( Employee.class, id );

or

List<Long> idList = . . . ;List<Employee> emps = em.find( idList );

165Versant JPA Developer's Guide

Cascading Persistence

(Returning a list of entities is a V/JPA extension. Refer to your V/JPA Javadoc API reference formore information.)

In V/JPA, the find() implementation follows the same behavior as the method contains(). Thatis, find()will return null in the same circumstance that contains()would return false. Specifically,the find()method will return null—or the corresponding List element is null—in the followingcases.

• if the specified entity is detached or removed either by a direct detach() or remove() call orthrough a cascaded operation

• if the entity is new and has not yet been made persistent either by a direct persist() call orthrough a cascaded operation

This is not a deviation from the JPA specification and is a permitted implementation strategy.

23.9. Query SupportFocusing on the efficient support for retrieving objects via navigation, the V/JPA Server queryengine does not support all JPA query language constructs. For a detailed summary of all supportedand unsupported JPQL expressions, refer to Section 24.2, “JPQL Support” pg. 172.

Unsupported expressions are a deviation from the JPA specification.

23.10. Object CloningIf you clone a persistent entity, Versant JPA needs to ensure that this newly created object is notpart of the same persistent context as the original object, but is, rather, a disconnected object. Toensure this, the enhancer injects a clonemethod into the top-most persistent class or modifies anyuser-defined clone method of the top-most persistent class.

This will cover all but some extreme corner-case clone implementations. For these cases, VersantJPA imposes the following restrictions.

• A user-written clonemethodmay not call any JPA API methods (e.g., EntityManager.persist())

• A user-written clone method may not manipulate any enhancer injected fields (the field namesstarting with _vjpa) via reflection

Versant JPA Developer's Guide166

Query Support

Cloning is not discussed in detail by the JPA specification. However, this behavior is a natural requirement.

23.11. Entity Lifecycle ListenersThe JPA specification does not strictly mandate at what point a lifecycle listener is called, allowinga degree of flexibility for the vendor. The following describes how and when various lifecyclelisteners are called in Versant JPA.

The pre-persist and pre-remove listener events are performed, first, when the respective persistand remove operations are called.

The pre-update listener event is performed before the update operation is flushed to the database.

The post-persist, post-remove and post-update listener events are performed immediately afterthe respective operations are executed during flush. Be aware that the commit operation implicitlytriggers a flush and that the listener events are performed after the flush but before the transactionis actually committed to the database.

Lifecycle callbacks are permitted to modify the non-relationship state of an entity (for example,modifying an int or string field). This is not a problem for pre-persist, pre-remove, post-removeor pre-update. However, if a post-persist, post-update or post-load listener modifies an entity, theentity is then treated as a “dirty” object which will need to be flushed, again, to the database.

For an explicit flush invocation, this simplymeans that after flush there are still dirty objects whichwill be flushed again with the next flush invocation or during commit. For a commit invocation, ifany dirty objects are created they are immediately flushed again before the database commit isexecuted. This is done in a loop until no dirty objects are created. This implies that if your listener(e.g., post-update) always unconditionally makes your object dirty, the commit call will be anendless loop.

23.12. Locking and Concurrency ControlThis section looks at JPA locking and concurrency control and how V/JPA conforms to or differsfrom the JPA specification.

167Versant JPA Developer's Guide

Entity Lifecycle Listeners

Lock scope

JPA is conceived for relational data stores. The JPA specification for locking and concurrency controlassumes that the data scope for a given entity may be distributed across multiple rows in differenttables. This does not apply to V/JPA since the entity is represented directly as an object in the datastore. Potential problems associated with having different parts of an entity having different lockmodes are completely avoided. Therefore, scope-related properties such asjavax.persistence.lock.scope have no relevance to V/JPA and are ignored, if specified.

Query with lock mode

If a query with a lock mode set returns scalar data, the underlying entities are not locked.

This is a deviation from the JPA specification.

Non-existing entities

For pessimistic locking, the JPA specification states that the EntityManager.lock()methods throwthe exception EntityNotFoundException if the entity to be locked does not exist in the database.However, in V/JPA, attempting to set a lock on a non-existent entity will not generate an error andno exception is thrown.

This is a deviation from the JPA specification.

Dirty reads

The JPA specification states that dirty reads are not allowed. However, V/JPA allows dirty reads ofan object, regardless of the lock mode set on the object.

This is a deviation from the JPA specification.

Versioning

JPA provides the annotation @Version to define a field for entity version validation, for example,when using optimistic locking. In V/JPA, a timestamp field is automatically appended to all entityobjects and version validation is supported without the need for an application-defined versionfield.

Versant JPA Developer's Guide168

Locking and Concurrency Control

This has the beneficial effect that entity objects in V/JPA are always participating in optimisticconcurrency control. A side effect of automatic validation is that objects which are subject totimestamp validation (e.g., objects with LockModeType.OPTIMISTIC applied, but not modified) arestrongly referenced until commit time. Updated, inserted and deleted objects are also stronglyreferenced until they are flushed (and then protected by awrite lock). And,merge operations alwayscause a timestamp validation at flush/commit time.

This is a deviation from the JPA specification.

The V/JPA entity timestamp field is type int (four-byte) and is used as an incrementing modification counter.You can provide a @Version field in your entity classes. The allowed types are restricted to int, Integer, longand Long. Declaring such a field just exposes the internal timestamp to your application. Since the field ismaintained by the V/JPA Server, writing this field is not permitted.

23.13. Mapped SuperclassesIn Versant JPA, a mapped superclass is treated as a normal entity class, including how the accesstype for fields is determined. Mapped superclasses differ from normal V/JPA entity classes in thefollowing ways.

• In addition to the standard V/JPA@Id field types long and java.lang.Long, the@Id field of yourmapped superclassmay be of type Object or Serializable. At runtime, Versant JPAwill populatean Object or Serializable@Id field with a java.lang.Long instance. (Allowing type Object orSerializable@Id fields provides support for the AbstractPersistable<PK> type from the SpringData project).

• V/JPA mapped superclass instances may not be stored directly but only occur in the database aspart of an inheritance tree.

• Because instances of V/JPA mapped superclasses are not operated on directly, they should notbe listed in the persistence unit (persistence.xml file) for the application.

This is a deviation from the JPA standard.

169Versant JPA Developer's Guide

Mapped Superclasses

23.14. Serializable FieldsIn Versant JPA, in order for any field to be serialized when written to the database, the field mustbe annotated with the @Lob annotation. This is the case for all fields you wish to serialize, even ifserializationwould be the default storagemechanism. Attempting to store a field that would defaultto serializable but does not have the @Lob annotation results in an PersistenceException exception.(Using the @Lob annotation for a non-serializable type will cause the exceptionInvalidAnnotationUsageException.)

Refer to Chapter 16, Large Objects pg. 117 for more information regarding the @Lob annotation inV/JPA.

This is a deviation from the JPA standard.

23.15. XAResource ImplementationisSameRM()method

The XAResource.isSameRM()method is called by the TransactionManager instance when enlistingan XAResource instance with a transaction. The purpose of the method is to determine whether thetransaction already has an enlisted XAResource instance that represents the same ResourceManagerinstance (i.e., the same V/JPA database). The V/JPA implementation of the isSameRM()method willalways return false. A subsequent join call is not a legal operation. Such a join call(XAResource.start(xid, XAResource.TMJOIN), either by the application server or manually) willthrow the exception XAException.

This implementation follows from the point that the definition of isSameRM() does not considercached information above the XAResource instance. However, this is the case with a persistencecontext holding unflushed information (e.g., modified entities). It is not enough to say that twoXA resources share the same database. Inconsistencies would arise by returning true if bothXAResource instances point to the same database, but do not share the same entity cache.

Versant JPA Developer's Guide170

Serializable Fields

Chapter 24. Currently Supported Features

Sections• JPA Features• JPQL Support

24.1. JPA FeaturesA listing of general JPA feature support in V/JPA as well as currently unsupported features andfeatures with limited support

Supported Features

The following JPA features are supported in this release of Versant JPA.

• Java Platform, Standard Edition Persistence

Java Platform, Enterprise Edition persistence

(Java JDK 1.7)

• JPQL

(Currently, only a subset of the full JPQL language is provided. Refer to Section 24.2, “JPQLSupport” pg. 172.)

• Object lifecycle mechanisms

persist, remove, refresh, detach, merge and cascading of these operations

• Transaction management

• Runtime or build-time enhancement of entity classes

• Distributed databases

• Automatic schema evolution

171Versant JPA Developer's Guide

Limited Support or Unsupported

The following JPA features are not yet supported or only partially supported in this release.

• The following Java classes are currently not supported.

java.math.BigDecimaljava.math.BigIntegerjava.util.Calendar

If your class contains an attribute of any of the above types, an exception, PersistenceException,is thrown when you create an EntityManagerFactory instance.

• Criteria query language

Currently, not supported.

• Embedded Objects

Currently, the @embedded annotation is ignored; embedded obects are stored as first-class objects.

• Bean Validation

Currently, not supported.

24.2. JPQL SupportThe following summarizes the current support for JPQL expressions in V/JPA.

Extended JPQL Support

The following describes V/JPA-specific extensions to the JPQL specification.

• As of JPA 2.0, the JPQL grammar has not explicitly specified support for the the use of collectionmember declaration variables of primitive type in comparisons. For example, constructs such asthe following where b.keywords is a collection of type String.

SELECT b from Book b, in(b.keywords) k where k like '%grammar%'

Versant JPA Developer's Guide172

JPQL Support

V/JPA does support this query construct as an extension to the current JPQL specification (andin anticipation of the inclusion of such constructs in the JPA 2.1 specification). The V/JPAimplementation has the restriction that these variables cannot be used with IN/MEMBERcomparisons.

Supported JPQL expressions

The following table shows the currently supported JPQL expressions.

Table 24.1. JPQL—Supported Expressions in V/JPA

CommentExampleJPQL Expressionlimited support for Id attributequeries (refer to Section 12.2,

select o from Person whereo.age > :age

Comparison

“Using the Entity Identifier inQueries” pg. 97)

select o from Person whereo.age > :age

Named Parameters

select o from Person whereo.age > ?1

Positional Parameters

select o from Person whereo.age between 8 and 5

Between Expression

select o from Person whereo.age > 5

Literal

select o from Person whereo.age in (5, 6)

In Expression

select o from Person whereo.age in :inParams, select o

In Expression(param)

from Person where o.age in(:inParam1, :inParam2)

select o from Person whereo.name like '%en'

Like Expression

only supported for singlereferences

select o from Person whereo.address is not null

Is [not] null Expression

select o from Employee o, in(o.address) adds whereadds.street = :name

CollectionMemberDeclarations

173Versant JPA Developer's Guide

JPQL Support

CommentExampleJPQL Expressionnot supported for identificationvariables (select p from P pwhere p member of p.siblings).

select o from Employee owhere :address member ofo.address

Collection Member Expressions

select o from Person whereo.age > :age order by o.ageasc

Order by Expression

delete from Person (removesall Person entities)

Delete by Query

Unsupported JPQL expressions

The following JPQL expressions are currently not supported in V/JPA.

Table 24.2. JPQL—Unsupported Expressions in V/JPA

CommentExampleJPQL ExpressionOnly limited support planned.select o from Person where

o.age in (select a.age fromEmployee a)

In Expression(subquery)

Only limited support planned.select auth from Author authwhere auth.salary >=

All or Any Expressions

all(select a.salary fromAuthor a where a.magazine =auth.magazine)

Only limited support planned.select o from Employee owhere exists (select e from

Exists

Employee e where e.baseField= o.baseField)

select mag from Magazine magwhere mag.articles is empty

Collection ComparisonExpressions

Not planned.Subqueries

Functional Expressions

select max(o.age) from Persono

Aggregate Functions

Versant JPA Developer's Guide174

JPQL Support

CommentExampleJPQL ExpressionCurrently, not supported.select c from Company c,

in(c.employees) e whereTYPE(e) = FulltimeEmployee

Entity TYPE() Expressions

Currently, not supported.select newcom.company.PublisherInfo(pub.id,

Constructor Expressions

pub.revenue, mag.price) fromPublisher pub joinpub.magazines mag wheremag.price > 5.00

Not planned.Distinct

Not planned.Group By/Having

Not planned.Update Queries

Not planned.Join

175Versant JPA Developer's Guide

JPQL Support

Versant JPA Developer's Guide176

Chapter 25. JPA Public API Support

Sections• Package javax.persistence

- Primary Persistence Interfaces- Query-related Interfaces

• Package javax.persistence.spi• Package javax.persistence.criteria• Package javax.persistence.metamodel• Annotations

- Vendor-specific Annotations- JPA Annotation Support

25.1. Package javax.persistence

25.1.1. Primary Persistence Interfaces

Table 25.1. Interface EntityManager

StatusCommentsMethodSupportedclear()

Supportedclose()

Supportedcontains(entity)

SupportedcreateNamedQuery(name)

SupportedcreateNamedQuery(name,resultClass)

N/ANot applicable, no native SQL queries for V/JPA ServercreateNativeQuery(sqlString)

N/ANot applicable, no native SQL queries for V/JPA ServercreateNativeQuery(sqlString,resultClass)

N/ANot applicable, no native SQL queries for V/JPA ServercreateNativeQuery(sqlString,resultSetMapping)

177Versant JPA Developer's Guide

StatusCommentsMethodCurrently,notsupported

createQuery(criteriaQuery)

SupportedcreateQuery(qlString)

SupportedcreateQuery(qlString,resultClass)

Supporteddetach(entity)

Supportedfind(entityClass, primaryKey)

Supportedfind(entityClass, primaryKey,lockMode)

SupportedCurrently only the cache mode properties aresupported. See section 3.7.2 of the specification.

find(entityClass, primaryKey,lockMode, properties)

SupportedCurrently only the cache mode properties aresupported. See section 3.7.2 of the specification.

find(entityClass, primaryKey,properties)

Supportedflush()

Currently,notsupported

getCriteriaBuilder()

N/ADeprecated, use unwrap(cls) insteadgetDelegate()

SupportedgetEntityManagerFactory()

SupportedgetFlushMode()

SupportedgetLockMode(entity)

Currently,notsupported

getMetamodel()

SupportedgetProperties()

SupportedgetReference(entityClass,primaryKey)

SupportedgetTransaction()

SupportedisOpen()

SupportedjoinTransaction()

Versant JPA Developer's Guide178

Package javax.persistence

StatusCommentsMethodSupportedAttempting to set a (pessimistic) lock on a non-existing

object does not result in an error. (Refer toSection 23.12, “Non-existing entities” pg. 168.)

lock(entity, lockMode)

SupportedRestriction: Setting properties currently has no effectlock(entity, lockMode,properties)

Supportedmerge(entity)

Supportedpersist(entity)

Supportedrefresh(entity)

Supportedrefresh(entity, lockMode)

SupportedCurrently only the cache mode properties aresupported. See section 3.7.2 of the specification.

refresh(entity, lockMode,properties)

SupportedCurrently only the cache mode properties aresupported. See section 3.7.2 of the specification.

refresh(entity, properties)

Supportedremove(entity)

SupportedsetFlushMode(flushMode)

SupportedCurrently only the cache mode properties aresupported. See section 3.7.2 of the specification.

setProperty(propertyName,value)

Supporteduseunwrap(com.versant.jpa.VersantEntityManager.class)to access Versant vendor-specific extensions

unwrap(cls)

Table 25.2. Interface EntityManagerFactory

StatusCommentsMethodSupportedclose()

SupportedcreateEntityManager()

SupportedcreateEntityManager(java.util.Map map)

SupportedgetCache()

Currently, not supportedgetCriteriaBuilder()

Currently, not supportedgetMetamodel()

SupportedgetPersistenceUnitUtil()

SupportedgetProperties()

179Versant JPA Developer's Guide

Package javax.persistence

StatusCommentsMethodSupportedisOpen()

Table 25.3. Interface EntityTransaction

StatusCommentsMethodSupportedbegin()

Supportedcommit()

SupportedgetRollbackOnly()

SupportedisActive()

Supportedrollback()

SupportedsetRollbackOnly()

Table 25.4. Interface Cache

StatusCommentsMethodSupportedcontains(cls, primaryKey)

Currently, not supportedevict(cls)

Supportedevict(cls, primaryKey)

SupportedevictAll()

Table 25.5. Interface PersistenceUnitUtil

StatusCommentsMethodSupportedgetIdentifier(entity)

SupportedisLoaded(entity)

SupportedisLoaded(entity, attributeName)

Table 25.6. Interface PersistenceUtil

StatusCommentsMethodSupportedisLoaded(entity)

SupportedisLoaded(entity, attributeName)

Versant JPA Developer's Guide180

Package javax.persistence

Table 25.7. Class Persistence

StatusCommentsMethodSupportedcreateContainerEntityManagerFactory(persistenceUnit,

properties)

SupportedcreateEntityManagerFactory(persistenceUnitName,properties)

SupportedgetProviderUtil()

25.1.2. Query-related Interfaces

Table 25.8. Interface Query

StatusCommentsMethodNot plannedexecuteUpdate()

Currently, notsupported

getFirstResult()

SupportedgetFlushMode()

SupportedCurrently only the cache mode properties aresupported. See section 3.7.2 of thespecification.

getHints()

SupportedgetLockMode()

Currently, notsupported

getMaxResults()

SupportedgetParameter(int position)

SupportedgetParameter(int position, type)

SupportedgetParameter(name)

SupportedgetParameter(name, type)

SupportedgetParameters()

SupportedgetParameterValue(int position)

SupportedgetParameterValue(Parameter<T>param)

SupportedgetParameterValue(name)

SupportedgetResultList()

181Versant JPA Developer's Guide

Package javax.persistence

StatusCommentsMethodSupportedgetSingleResult()

SupportedisBound(Parameter<?> param)

Currently, notsupported

setFirstResult(int startPosition)

SupportedsetFlushMode(FlushModeTypeflushMode)

SupportedCurrently only the cache mode properties aresupported. See section 3.7.2 of thespecification.

setHint(hintName, value)

SupportedsetLockMode(lockMode)

Currently, notsupported

setMaxResults(int maxResult)

SupportedsetParameter(int position,java.util.Calendar value,temporalType)

SupportedsetParameter(int position,java.util.Date value, temporalType)

SupportedsetParameter(int position, value)

SupportedsetParameter(param,java.util.Calendar value,temporalType)

SupportedsetParameter(param, java.util.Datevalue, temporalType)

SupportedsetParameter(param, value)

SupportedsetParameter(name,java.util.Calendar value,temporalType)

SupportedsetParameter(name, java.util.Datevalue, temporalType)

SupportedsetParameter(name, value)

Supporteduseunwrap(com.versant.jpa.VersantQuery.class)to access Versant vendor-specific extensions

unwrap(cls)

Versant JPA Developer's Guide182

Package javax.persistence

Table 25.9. Interface TypedQuery<X>

StatusCommentsMethodSupportedgetResultList()

SupportedgetSingleResult()

Currently, not supportedsetFirstResult(startPosition)

SupportedsetFlushMode(flushMode)

SupportedCurrently only thecache mode

setHint(hintName, value)

properties aresupported. Seesection 3.7.2 of thespecification.

SupportedsetLockMode(lockMode)

Currently, not supportedsetMaxResults(maxResult)

SupportedsetParameter(position, java.util.Calendar value,temporalType)

SupportedsetParameter(position, java.util.Date value,temporalType)

SupportedsetParameter(position, value)

SupportedsetParameter(param, java.util.Calendar value,temporalType)

SupportedsetParameter(param, java.util.Date value,temporalType)

SupportedsetParameter(param, value)

SupportedsetParameter(name, java.util.Calendar value,temporalType)

SupportedsetParameter(name, java.util.Date value,temporalType)

SupportedsetParameter(name, value)

Table 25.10. Interface Parameter<T>

StatusCommentsMethodSupportedgetName()

183Versant JPA Developer's Guide

Package javax.persistence

StatusCommentsMethodCurrently, not supportedonly required for Criteria

queriesgetParameterType()

SupportedgetPosition()

Table 25.11. Interface Tuple

StatusCommentsMethodCurrently, not supportedget(int i)

Currently, not supportedget(int i, type)

Currently, not supportedget(alias)

Currently, not supportedget(alias, type)

Currently, not supportedget(TupleElement<X> tupleElement)

Currently, not supportedgetElements()

Currently, not supportedtoArray()

Table 25.12. Interface TupleElement<X>

StatusCommentsMethodCurrently, not supportedgetAlias()

Currently, not supportedgetJavaType()

25.2. Package javax.persistence.spi

Table 25.13. Interface Summary—javax.persistence.spi

StatusCommentsInterfaceinterface implementationcomplete

A persistence provider supplies aninstance of this interface to the

ClassTransformer

PersistenceUnitInfo.addTransformermethod.

interface implementationcomplete

Interface implemented by the persistenceprovider.

PersistenceProvider

Versant JPA Developer's Guide184

Package javax.persistence.spi

StatusCommentsInterface(not to be implemented)Determine the list of persistence providers

available in the runtime environment.PersistenceProviderResolver

(not to be implemented)Interface implemented by the containerand used by the persistence providerwhencreating an EntityManagerFactory.

PersistenceUnitInfo

interface implementationcomplete

Utility interface implemented by thepersistence provider.

ProviderUtil

Table 25.14. Class Summary—javax.persistence.spi

StatusCommentsClass(not to be implemented)Holds the global

PersistenceProviderResolverinstance.

PersistenceProviderResolverHolder

25.3. Package javax.persistence.criteria

(Currently, package is not supported.)

25.4. Package javax.persistence.metamodel

(Currently, package is not supported.)

25.5. Annotations

25.5.1. Vendor-specific Annotations

The following are the available vendor-specific annotations for Versant JPA.

185Versant JPA Developer's Guide

Package javax.persistence.criteria

Vendor-specific Annotations

EqualsById

This directs a collection to use the entity identity, rather than the equals()method, foroperations that require entity comparisons, e.g., add(), remove(), etc. Refer to Section 13.1,“Collection Optimization” pg. 99 for information.

Index

Class-level annotation to define a single simple or compound index. Refer to Chapter 17,Indexes pg. 119 for information.

Indexes

Class-level annotation to define multiple simple or compound indexes. Refer to Chapter 17,Indexes pg. 119 for information.

25.5.2. JPA Annotation Support

General remark on mapping

Many of the JPA annotations are used for defining object/relational mapping. The Versant JPAdatabase is an object database. There is no need for this mapping, as V/JPA Server stores objectsdirectly. Because of this, Versant JPA will ignore annotations which are only important for mappingpurposes. These annotations are marked in the following list with the status “Mapping”.

Table 25.15. Annotations

StatusCommentsAnnotationSupportedAccess

MappingRefer to the general remark on mappingAssociationOverride

MappingRefer to the general remark on mappingAssociationOverrides

MappingRefer to the general remark on mappingAttributeOverride

MappingRefer to the general remark on mappingAttributeOverrides

SupportedV/JPA ignores the hint “optional=false”Basic

Versant JPA Developer's Guide186

Annotations

StatusCommentsAnnotationAttributeswith the Basic annotation are alwaysfetched EAGER, V/JPA ignores the argument“fetch=LAZY”

SupportedCacheable

MappingRefer to the general remark on mappingCollectionTable

MappingRefer to the general remark on mappingColumn

N/ANot applicable, no native SQL queries for V/JPAServer

ColumnResult

MappingRefer to the general remark on mappingDiscriminatorColumn

MappingRefer to the general remark on mappingDiscriminatorValue

MappingRefer to the general remark on mappingElementCollection

Currently, notsupported

Embeddable

Currently, notsupported

Embedded

Currently, notsupported

EmbeddedId

SupportedEntity

SupportedEntityListeners

N/ANot applicable, no native SQL queries for V/JPAServer

EntityResult

SupportedEnumerated

SupportedExcludeDefaultListeners

SupportedExcludeSuperclassListeners

N/ANot applicable, no native SQL queries for V/JPAServer

FieldResult

N/AVersant JPA supports only (server-side)generated type long Ids (LOIDs - Logical ObjectIDs)

GeneratedValue

SupportedRestriction: Id has to be a long/Long attribute;setting the ID by the user is not permitted

Id

187Versant JPA Developer's Guide

Annotations

StatusCommentsAnnotationN/AVersant JPA supports only (server-side)

generated type long Ids (LOIDs - Logical ObjectIDs)

IdClass

MappingRefer to the general remark on mappingInheritance

MappingRefer to the general remark on mappingJoinColumn

MappingRefer to the general remark on mappingJoinColumns

MappingRefer to the general remark on mappingJoinTable

SupportedLob

SupportedValues for Elements “targetEntity” and“mappedBy” will be ignored

ManyToMany

mappedBy: Refer to the general remark onmapping

SupportedV/JPA ignores the hint “optional=false”ManyToOne

Values for Elements “targetEntity” will beignored

MappingRefer to the general remark on mappingMapKey

Currently, notsupported

MapKeyClass

MappingRefer to the general remark on mappingMapKeyColumn

SupportedMapKeyEnumerated

MappingRefer to the general remark on mappingMapKeyJoinColumn

MappingRefer to the general remark on mappingMapKeyJoinColumns

N/AV/JPA does not require this to be defined forjava.util.Date or java.util.Calendar (the

MapKeyTemporal

latter is currently not supported). All date typesare transparently stored in the V/JPA Serverinternal date type.

SupportedFor details refer to Section 23.13, “MappedSuperclasses” pg. 169.

MappedSuperclass

MappingRefer to the general remark on mappingMapsId

N/ANot applicable, no native SQL queries for V/JPAServer

NamedNativeQueries

Versant JPA Developer's Guide188

Annotations

StatusCommentsAnnotationN/ANot applicable, no native SQL queries for V/JPA

ServerNamedNativeQuery

SupportedNamedQueries

SupportedNamedQuery

SupportedValues for Elements “targetEntity”,“mappedBy” and “orphanRemoval” will beignored

OneToMany

mappedBy: Refer to the general remark onmapping

SupportedV/JPA ignores the hint “optional=false”OneToOne

Values for Elements “targetEntity”,“mappedBy” and “orphanRemoval” will beignored

mappedBy: Refer to the general remark onmapping

Currently, notsupported

OrderBy

Currently, notsupported

OrderColumn

N/Aprovided by the container in a Java EE contextPersistenceContext

N/Aprovided by the container in a Java EE contextPersistenceContexts

N/Aprovided by the container in a Java EE contextPersistenceProperty

N/Aprovided by the container in a Java EE contextPersistenceUnit

N/Aprovided by the container in a Java EE contextPersistenceUnits

SupportedPostLoad

SupportedPostPersist

SupportedPostRemove

SupportedPostUpdate

SupportedPrePersist

SupportedPreRemove

SupportedPreUpdate

189Versant JPA Developer's Guide

Annotations

StatusCommentsAnnotationMappingRefer to the general remark on mappingPrimaryKeyJoinColumn

MappingRefer to the general remark on mappingPrimaryKeyJoinColumns

Currently, notsupported

QueryHint

MappingRefer to the general remark on mappingSecondaryTable

MappingRefer to the general remark on mappingSecondaryTables

N/AVersant JPA supports only (server-side)generated type long Ids (LOIDs - Logical ObjectIDs)

SequenceGenerator

N/ANot applicable, no native SQL queries for V/JPAServer

SqlResultSetMapping

N/ANot applicable, no native SQL queries for V/JPAServer

SqlResultSetMappings

MappingRefer to the general remark on mappingTable

N/AVersant JPA supports only (server-side)generated type long Ids (LOIDs - Logical ObjectIDs)

TableGenerator

N/AV/JPA does not require this to be defined forjava.util.Date or java.util.Calendar (the

Temporal

latter is currently not supported). All date typesare transparently stored in the V/JPA Serverinternal date type.

SupportedTransient

MappingRefer to the general remark on mappingUniqueConstraint

SupportedVersant JPA allows up to one version field perentity class. Defining a version attribute simply

Version

makes the (always existent) V/JPA Serverinternal database timestamp visible to theapplication (which is of type int, 4-byte; thesemantic is an incremented version number,not a time value).

The application is not allowed to update this.

Versant JPA Developer's Guide190

Annotations

StatusCommentsAnnotationThe following types are supported: int,Integer, long, Long.

Not supported: short, Short, Timestamp.

191Versant JPA Developer's Guide

Annotations

Versant JPA Developer's Guide192

Appendix A. Server Statistics Reference

Sections• Database Statistic Names

A.1. Database Statistic NamesThe following statistics can be collected for a database.

Table A.1. Names of Database Statistics

DescriptionStatisticBytes written to logical logdb_bf_llog_bytes_written

Number of writes to logical logdb_bf_llog_flushes

Bytes written to physical logdb_bf_plog_bytes_written

Number of writes to physical logdb_bf_plog_flushes

Derived statisticdb_cache_hit_ratio db = db_data_located db /(db_data_located db + db_data_reads db)

db_cache_hit_ratio db, where db isthe name of a database

System checkpoints.db_checkpoints

Pages found in database page cachedb_data_located

Pages read from sysvol + added volumesdb_data_reads

Pages written to sysvol + added volumesdb_data_writes

Bytes of storage availabledb_disk_free

Bytes of storage reserved by classesdb_disk_reserved

Events defineddb_ev_defined

System events delivereddb_ev_sys_delivered

System events raiseddb_ev_sys_raised

User events delivereddb_ev_user_delivered

User events raiseddb_ev_user_raised

193Versant JPA Developer's Guide

DescriptionStatisticDerived statisticdb_inst_cache_hit_ratio db = delta db_data_locateddb / (delta db_data_located db + deltadb_data_reads db)

db_inst_cache_hit_ratio db, wheredb is the name of a database

Deadlocks occurreddb_lock_deadlocks

Timeouts waiting for locksdb_lock_timeouts

Seconds clients spent waiting for locksdb_lock_wait_time

Lock waits which occurreddb_lock_waits

Locks requested and granteddb_locks_granted

Bytes read from front enddb_net_bytes_read

Bytes written to front enddb_net_bytes_written

Seconds reading from front enddb_net_read_time

Reads from front enddb_net_reads

Database RPCs received from clientsdb_net_rpcs

Seconds writing to front enddb_net_write_time

Writes to front enddb_net_writes

Connections waiting for locksdb_obe_locks_waiting

Objects received from front enddb_obj_received

Objects sent to front enddb_obj_sent

Objects read during B-tree querydb_qry_btree_objs

Seconds spent in B-tree querydb_qry_btree_time

Objects read during hash querydb_qry_hash_objs

Seconds spent in hash querydb_qry_hash_time

Objects read during sequential scan querydb_qry_scan_objs

Seconds spent in sequential scan querydb_qry_scan_time

Active transactionsdb_xact_active

Transactions committeddb_xact_committed

Transactions rolled backdb_xact_rolled_back

Transactions starteddb_xact_started

Versant JPA Developer's Guide194

Database Statistic Names

DescriptionStatisticAssociative table root pages found in database pagecache

db_at_root_located

Associative table root pages read from sysvol and addedvolumes

db_at_root_read

Associative table leaf pages found in database page cachedb_at_leaf_located

Associative table leaf pages read from sysvol and addedvolumes

db_at_leaf_located

195Versant JPA Developer's Guide

Database Statistic Names

Versant JPA Developer's Guide196