Forum Replies Created
-
AuthorPosts
-
aleprovaMember
ORM OBJECT RELATIONAL MAPPING
It mapping between the objects and the database.ORM, in essence, works by (reversibly) transforming data from one representation to another.
CRUD (create, read, update, delete) operations
– Dati persistent
– Operation:ORM OBJECT RELATIONAL MAPPING
It mapping between the objects and the database.ORM, in essence, works by (reversibly) transforming data from one representation to another.
CRUD (create, read, update, delete) operations
– Dati persistent
– Operation:
â– Storage, organization, and retrieval of structured data
â– Concurrency and data integrity
â– Data sharing
– GranularitÃ
If one application holds a lock on a database object, another application might not be able to access that object. For this reason, row-level locks, which minimize the amount of data that is locked and therefore inaccessible, are better for maximum concurrency than block-level, data partition-level or table-level locks. However, locks require storage and processing time, so a single table lock minimizes lock overhead.
The LOCKSIZE clause of the ALTER TABLE statement specifies the scope (granularity) of locks at the row, data partition, block, or table level. By default, row locks are used. Only S (Shared) and X (Exclusive) locks are requested by these defined table locks. The ALTER TABLE statement LOCKSIZE ROW clause does not prevent normal lock escalation from occurring.
A permanent table lock defined by the ALTER TABLE statement might be preferable to a single-transaction table lock using LOCK TABLE statement in the following cases:
– The table is read-only, and will always need only S locks. Other users can also obtain S locks on the table.
– The table is usually accessed by read-only applications, but is sometimes accessed by a single user for brief maintenance, and that user requires an X lock. While the maintenance program runs, the read-only applications are locked out, but in other circumstances, read-only applications can access the table concurrently with a minimum of locking overhead.
PAG 52
Cap2.
The persistence consists in storing data in a relational database using SQL. Hibernate applications define persistent classes that are “mapped†to database tables.
package hello;
public class Message {
private Long id;
private String text;
private Message nextMessage;
private Message() {
}
public Message(String text) {
this.text = text;
}
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
public String getText() {
return text;
}
}
public void setText(String text) {
this.text = text;
}
public Message getNextMessage() {
return nextMessage;
}
public void setNextMessage(Message nextMessage) {
this.nextMessage = nextMessage;
}
}
It prints “Hello World” to the console.
Message message = new Message(“Hello World”);
System.out.println( message.getText() );
Our persistent class can be used in any execution context at all. Of course, you came here to see Hibernate itself, so let’s save a new Message to the database:
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
Message message = new Message(“Hello World”);
session.save(message);
tx.commit();
session.close();
This code calls the Hibernate Session and Transaction interfaces. It results in the execution of something similar to the following SQL:
insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)
values (1, ‘Hello World’, null)
We can also assume that the MESSAGES table already exists.
Session newSession = getSessionFactory().openSession();
Transaction newTransaction = newSession.beginTransaction();
List messages = newSession.find(“from Message as m order by m.text asc”);
//
HIBERNATE QUERY:
select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID
from MESSAGES m
order by m.MESSAGE_TEXT asc
//
System.out.println( messages.size() + ” message(s) found:” );
for ( Iterator iter = messages.iterator(); iter.hasNext(); ) {
Message message = (Message) iter.next();
System.out.println( message.getText() );
}
newTransaction.commit();
newSession.close();
All SQL is generated at runtime.
XML MAPPING HIBERNATE CODE
<?xml version=”1.0″?>
<!DOCTYPE hibernate-mapping PUBLIC
“-//Hibernate/Hibernate Mapping DTD//EN”
“http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd”>
<hibernate-mapping>
<class
name=”hello.Message”
table=”MESSAGES”>
<id name=”id” column=”MESSAGE_ID”>
<generator class=”increment”/>
</id>
<property name=”text” column=”MESSAGE_TEXT”/>
<many-to-one name=”nextMessage” cascade=”all” column=”NEXT_MESSAGE_ID”/>
</class>
</hibernate-mapping>
The Hibernate interfaces may be approximately classified as follows:
â– Interfaces called by applications to perform basic CRUD and querying operations. These interfaces are the main point of dependency of application business/control logic on Hibernate. They include Session, Transaction, and Query.
â– Interfaces called by application infrastructure code to configure Hibernate, most importantly the Configuration class.
â– Callback interfaces that allow the application to react to events occurring inside Hibernate, such as Interceptor, Lifecycle, and Validatable.
■Interfaces that allow extension of Hibernate’s powerful mapping functionality, such as UserType, CompositeUserType, and IdentifierGenerator. These interfaces are implemented by application infrastructure code (if necessary).
• SESSION
The Session interface is the primary interface used by Hibernate applications. Hibernate sessions are not thread safe and should by design be used by only one thread at a time.
• SESSION FACTORY
It’s intended to be shared among many application threads. There is typically a single SessionFactory for the whole application. However, if your application accesses multiple databases using Hibernate, you’ll need a SessionFactory for each database. The SessionFactory caches generated SQL statements and other mapping metadata that Hibernate uses at runtime.
The following code starts Hibernate:
Configuration cfg = new Configuration();
cfg.addResource(“hello/Message.hbm.xml”);
cfg.setProperties( System.getProperties() );
SessionFactory sessions = cfg.buildSessionFactory();
The location of the mapping file, Message.hbm.xml, is relative to the root of the application classpath.
If we had another persistent class, it would be defined in its own mapping file. You can load multiple mapping files by calling addResource() as often as you have to. Alternatively, if you follow the convention just described, you can use the method addClass(), passing a persistent class as the parameter:
SessionFactory sessions = new Configuration()
.addClass(org.hibernate.auction.model.Item.class)
.addClass(org.hibernate.auction.model.Category.class)
.addClass(org.hibernate.auction.model.Bid.class)
.setProperties( System.getProperties() )
.buildSessionFactory();
If another SessionFactory is needed—if there are multiple databases, for example—you repeat the process.
To specify configuration options, you may use any of the following techniques:
â– Used except for quick testing and prototypes:
â– Pass an instance of java.util.Properties to Configuration.setProperties().
â– Set system properties using java -Dproperty=value.
â– Place a file called hibernate.properties in the classpath.
â– Include <property> elements in hibernate.cfg.xml in the classpath.
• CONFIGURATION
The Configuration object is used to configure and bootstrap Hibernate. The application uses a Configuration instance to specify the location of mapping documents and Hibernate-specific properties and then create the SessionFactory.
Configuration in non-managed environment:
Java applications should use a pool of JDBC connections. There are three reasons for using a pool:
â– Acquiring a new connection is expensive.
â– Maintaining many idle connections is expensive.
â– Creating prepared statements is also expensive for some drivers.
hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://localhost/auctiondb
hibernate.connection.username = auctionuser
hibernate.connection.password = secret
hibernate.dialect = net.sf.hibernate.dialect.PostgreSQLDialect
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=300
hibernate.c3p0.max_statements=50
hibernate.c3p0.idle_test_period=3000
Specifying properties of the form hibernate.c3p0.* selects C3P0 as Hibernate’s connection pool.
Configuration managed environment:
A managed environment handles certain cross-cutting concerns, such as application security (authorization and authentication), connection pooling, and transaction management.
hibernate.connection.datasource = java:/comp/env/jdbc/AuctionDB
hibernate.transaction.factory_class =
net.sf.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class =
net.sf.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = net.sf.hibernate.dialect.PostgreSQLDialect
XML-based Configuration:
The hibernate.cfg.xml file may also specify the location of mapping documents.
?xml version=’1.0’encoding=’utf-8′?>
<!DOCTYPE hibernate-configuration
PUBLIC “-//Hibernate/Hibernate Configuration DTD//EN”
“http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd”>
<hibernate-configuration>
<session-factory name=”java:/hibernate/HibernateFactory”>
<property name=”show_sql”>true</property>
<property name=”connection.datasource”> java:/comp/env/jdbc/AuctionDB</property>
<property name=”dialect”> net.sf.hibernate.dialect.PostgreSQLDialect </property>
<property name=”transaction.manager_lookup_class”>
net.sf.hibernate.transaction.JBossTransactionManagerLookup
</property>
<mapping resource=”auction/Item.hbm.xml”/>
<mapping resource=”auction/Category.hbm.xml”/>
<mapping resource=”auction/Bid.hbm.xml”/>
</session-factory>
</hibernate-configuration>
Now you can initialize Hibernate using:
SessionFactory sessions = new Configuration() .configure().buildSessionFactory();
When configure() was called, Hibernate searched for a file named hibernate.cfg.xml in the classpath. If you wish to use a different filename or have Hibernate look in a subdirectory, you must pass a path to the configure() method:
SessionFactory sessions =
new Configuration().configure(“/hibernate-config/auction.cfg.xml”).buildSessionFactory();
Using an XML configuration file is certainly more comfortable than a properties file or even programmatic property configuration.
Logging
When you find yourself troubleshooting a difficult problem, you need to be able to see exactly what’s going on inside Hibernate. You can use logging to get a view of Hibernate’s internals. Hibernate logs all interesting events using Apache commons-logging, a thin abstraction layer that directs output to either Apache log4j (if you put log4j.jar in your classpath).
JNDI
è acronimo di Java Naming and Directory Interface. All’interno di un Application Server (e anche in applicazioni non necessariamente web). Tutte le operazioni fondamentali che si possono compiere in un Application Server possono essere rimappate utilizzando JNDI. Elenchiamo alcune delle principali operazioni che normalmente vengono compiute: Transazioni (UserTransaction & TransactionManager) Pool di Connessioni ai Database (Datasource) Pool di Connessioni Transazionali ai Database (XADatasource). Con JNDI si possono rimappare tutti i percorsi fisici a cui è necessario puntare, in una sorta di tabella chiave-valore, una specie di HashTable, che rende facilmente configurabile, e quindi portabile, la nostra applicazione. Per maggiori informazioni ed esempi vi invito caldamente a visitare i link correlati. In particolare nel primo link è mostrato come accedere a JNDI in un Application Server Bea Weblogic.
Finally, you have the hibernate.properties, hibernate.cfg.xml, and log4j.properties configuration files.
Or
JMX: JAVA MANAGEMENT EXTENSION
The JMX specification defines the following components:
■The JMX MBean—A reusable component (usually infrastructural) that exposes an interface for management (administration)
■The JMX container—Mediates generic access (local or remote) to the MBean
■The (usually generic) JMX client—May be used to administer any MBean via the JMX container
An application server with support for JMX (such as JBoss) acts as a JMX container and allows an MBean to be configured and initialized as part of the application server startup process.
<server>
<mbean code=”net.sf.hibernate.jmx.HibernateService” name=”jboss.jca:service=HibernateFactory, name=HibernateFactory”>
<depends>jboss.jca:service=RARDeployer</depends>
<depends>jboss.jca:service=LocalTxCM, name=DataSource</depends>
<attribute name=”MapResources”> auction/Item.hbm.xml, auction/Bid.hbm.xml </attribute>
<attribute name=”JndiName”> java:/hibernate/HibernateFactory </attribute>
<attribute name=”Datasource”> java:/comp/env/jdbc/AuctionDB </attribute>
<attribute name=”Dialect”> net.sf.hibernate.dialect.PostgreSQLDialect </attribute>
<attribute name=”TransactionStrategy”> net.sf.hibernate.transaction.JTATransactionFactory </attribute>
<attribute name=”TransactionManagerLookupStrategy”> net.sf.hibernate.transaction.JBossTransactionManagerLookup </attribute>
<attribute name=”UserTransactionName”> java:/UserTransaction </attribute>
</mbean>
</server>
• TRANSICTION
The Transaction interface is an optional API. Hibernate applications may choose not to use this interface, instead managing transactions in their own infrastructure code. A Transaction abstracts application code from the underlying transaction implementation allowing the application to control transaction boundaries via a consistent API.
• CALLBACK
Callback interfaces allow the application to receive a notification when something interesting happens to an object—for example, when an object is loaded, saved, or deleted. Hibernate applications don’t need to implement these callbacks, but they’re useful for implementing certain kinds of generic functionality, such as creating audit records. The Lifecycle and Validatable interfaces allow a persistent object to react to events relating to its own persistence lifecycle.
• TYPE
A Hibernate Type object maps a Java type to a database column type (actually, the type may span multiple columns). All persistent properties of persistent classes, including associations, have a corresponding Hibernate type. This design makes Hibernate extremely flexible and extensible.
• EXTENSION POINTS:
â– Primary key generation (IdentifierGenerator interface)
â– SQL dialect support (Dialect abstract class)
////Serve e a specificare quale database stiamo utilizzando oracledialect; mysqldialect ecc…
â– Caching strategies (Cache and CacheProvider interfaces)
â– JDBC connection management (ConnectionProvider interface)
â– Transaction management (TransactionFactory, Transaction, and TransactionManagerLookup interfaces)
â– ORM strategies (ClassPersister interface hierarchy)
â– Property access strategies (PropertyAccessor interface)
â– Proxy creation (ProxyFactory interface)
http://www.roseindia.net/hibernate/firstexample.shtml
ARCHITETTURA:
Session, Transaction, and Query
(Create and compile a persistent class (the initial Message, for example), copy Hibernate and its required libraries to the classpath together with a hibernate.properties file, and build a SessionFactory. The next section covers advanced Hibernate configuration options. Some of them are recommended, such as logging executed SQL statements for debugging or using the convenient XML configuration file instead of plain properties.)
Cap3.
You shouldn’t put code that addresses these cross-cutting concerns in the classes that implement the domain model. When these concerns start to appear in the domain model classes, we call this an example of leakage of concerns. The EJB standard tries to solve the problem of leaky concerns. Indeed, if we implemented our domain model using entity beans, the container would take care of some concerns for us (or at least externalize those concerns to the deployment descriptor). The EJB container prevents leakage of certain cross-cutting concerns using interception. An EJB is a managed component, always executed inside the EJB container. The container intercepts calls to your beans and executes its own functionality. Hibernate isn’t an application server, and it doesn’t try to implement all the cross-cutting concerns mentioned in the EJB specification. Hibernate is a solution for just one of these concerns: persistence. If you require declarative security and transaction management, you should still access your domain model via a session bean, taking advantage of the EJB container’s implementation of these concerns. Hibernate is commonly used together with the well-known session façade J2EE pattern. Much discussion has gone into the topic of persistence, and both Hibernate and EJB entity beans take care of that concern. However, Hibernate offers something that entity beans don’t: transparent persistence. Our Item class, for example, will not have any code-level dependency to any Hibernate API. Furthermore:
■Hibernate doesn’t require that any special superclasses or interfaces be inherited or implemented by persistent classes. Nor are any special classes used to implement properties or associations. Thus, transparent persistence improves code readability, as you’ll soon see.
â– Persistent classes may be reused outside the context of persistence, in unit tests or in the user interface (UI) tier, for example. Testability is a basic requirement for applications with rich domain models.
■In a system with transparent persistence, objects aren’t aware of the underlying data store; they need not even be aware that they are being persisted or retrieved. Persistence concerns are externalized to a generic persistence manager interface —in the case of Hibernate, the Session and Query interfaces.
By this definition of transparent persistence, you see that certain non-automated persistence layers are transparent (for example, the DAO pattern) because they decouple the persistence-related code with abstract programming interfaces.
The programming model we’ll introduce is a non-intrusive mix of JavaBean specification details, POJO best practices, and Hibernate requirements. A POJO declares business methods, which define behavior, and properties, which represent state. Some properties represent associations to other POJOs. It’s an implementation of the User entity of our domain model.
public class User implements Serializable {
private String username;
private Address address;
public User() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Address getAddress() {
return address;
public void setAddress(Address address) {
this.address = address;
}
…
}
}
You use properties to express associations between POJO classes, and you use accessor methods to navigate the object graph at runtime.
scaffolding code:codice di “collegamentoâ€(ER model).
For example let’s implement the scaffolding code for the one-to-many self-association of Category:
public class Category implements Serializable {
private String name;
private Category parentCategory;
private Set childCategories = new HashSet();
public Category() { }
…
}
To allow bidirectional navigation of the association, we require two attributes. The parentCategory attribute implements the single-valued end of the association and is declared to be of type Category. The many-valued end, implemented by the child-Categories attribute, must be of collection type. We choose a Set, since duplicates are disallowed, and initialize the instance variable to a new instance of HashSet. We now have some private instance variables but no public interface to allow access from business code or property management by Hibernate. Let’s add some accessor methods to the Category class:
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set getChildCategories() {
return childCategories;
}
public void setChildCategories(Set childCategories) {
this.childCategories = childCategories;
}
public Category getParentCategory() {
return parentCategory;
}
public void setParentCategory(Category parentCategory) {
this.parentCategory = parentCategory;
}
Again, these accessor methods need to be declared public only if they’re part of the external interface of the persistent class, the public interface used by the application logic. The basic procedure for adding a child Category to a parent Category looks like this:
Category aParent = new Category();
Category aChild = new Category();
aChild.setParentCategory(aParent);
aParent.getChildCategories().add(aChild);
â– The parentCategory of the child must be set, effectively breaking the association between the child and its old parent (there can be only one parent for any child).
â– The child must be added to the child Categories collection of the new parent.
Programming models like EJB entity beans muddle this behavior by introducing container-managed relationships. The container automatically changes the other side of a relationship if one side is modified by the application.
Hibernate doesn’t care if property access methods are private or public, so we can focus on good API design.
One of the reasons we like to use JavaBeans-style access methods is that they provide encapsulation: The hidden internal implementation of a property can be changed without any changes to the public interface. This allows you to abstract the internal data structure of a class—the instance variables—from the design of the database. For example, if your database stores a name of the user as a single NAME column, but your User class has first name and last name properties, you can add the following persistent name property to your class:
Public class User {
private String firstname;
private String lastname;
…
public String getName() {
return firstname + ‘ ‘ + lastname;
}
public void setName(String name) {
StringTokenizer t = new StringTokenizer(name);
firstname = t.nextToken();
lastname = t.nextToken();
)
…
}
Later, you’ll see that a Hibernate custom type is probably a better way to handle many of these kinds of situations.
Hibernate will later use our accessor methods to populate the state of an object when loading the object from the database. Hibernate result in unnecessary SQL UPDATEs.
This kind of code should almost always be avoided in accessor methods:
public void setNames(List namesList) {
names = (String[]) namesList.toArray();
}
public List getNames() {
return Arrays.asList(names);
}
METADATA
ORM tools require a metadata format for the application to specify the mapping between classes and tables, properties and columns, associations and foreign keys, Java types and SQL types. This information is called the object/relational mapping metadata. It defines the transformation between the different data type systems and relationship representations.
XML mapping:
(DTD = document type definition)
<?xml version=”1.0″?>
<!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD//EN”
“http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd”>
<hibernate-mapping>
<class name=”org.hibernate.auction.model.Category” table=”CATEGORY”>
<id name=”id” column=”CATEGORY_ID” type=”long”>
<generator class=”native”/>
</id>
<property name=”name” column=”NAME” type=”string”/>
</class>
</hibernate-mapping>
If you omit the type, Hibernate will use the Hibernate type string by default. The <property> element (and especially the <column> element) also defines certain attributes that apply mainly to automatic database schema generation.
<property name=”initialPrice” column=”INITIAL_PRICE” not-null=”true”/>
<property name=”totalIncludingTax”
formula=”TOTAL + TAX_RATE * TOTAL”
type=”big_decimal”/>
The given SQL formula is evaluated every time the entity is retrieved from the database. The property doesn’t have a column attribute (or sub-element) and appears in an SQL SELECTs. Formulas may refer to columns of the database table, call SQL functions, and include SQL subselects. This example, mapping a derived property of item, uses a correlated subselect to calculate the average amount of all bids for an item:
<property name=”averageBidAmount”
formula=”( select AVG(b.AMOUNT)
from BID b
âž¾where b.ITEM_ID = ITEM_ID )”
type=”big_decimal”/>
access=”field”
Access to properties via accessor methods is considered best practice by the Hibernate community. It provides an extra level of abstraction between the Java domain model and the data model.
insert=”false”
update=”false”
The property name of the JavaBean is therefore immutable and can be read from the database but not modified in any way. If the complete class is immutable, set the immutable=”false” in the class mapping. The dynamic-update attribute tells Hibernate whether to include unmodified properties in the SQL UPDATE:
<class name=”org.hibernate.auction.model.User”
dynamic-insert=”true”
dynamic-update=”true”>
…
</class>
These are both class-level settings. Enabling either of these settings will cause Hibernate to generate some SQL at runtime, instead of using the SQL cached at startup time.
SQL schemas
You can specify a default schema using the hibernate.default_schema configuration option. Alternatively, you can specify a schema in the mapping document. A schema may be specified for a particular class or collection mapping:
<hibernate-mapping>
<class
name=”org.hibernate.auction.model.Category”
table=”CATEGORY”
schema=”AUCTION”>
…
</class>
</hibernate-mapping>
It can even be declared for the whole document:
<hibernate-mapping
default-schema=”AUCTION”>
..
</hibernate-mapping>
This isn’t the only thing the root <hibernate-mapping> element is useful for.
( http://www.mokabyte.it/2005/11/hibernate.htm
tag of XDOCLET:
http://xdoclet.sourceforge.net/xdoclet/tags/hibernate-tags.html#@hibernate_property__0__1_
using a script build.xml of Ant )
using declaration type
…
// Define a new column for the USER table
Column column = new Column();
column.setType(Hibernate.STRING);
column.setName(“ETA”);
column.setNullable(false);
column.setUnique(true);
userMapping.getTable().addColumn(column);
// Wrap the column in a Value
SimpleValue value = new SimpleValue();
value.setTable( userMapping.getTable() );
value.addColumn(column);
value.setType(Hibernate.STRING);
// Define a new property of the User class
Property prop = new Property();
prop.setValue(value);
prop.setName(“eta”);
userMapping.addProperty(prop);
// Build a new session factory, using the new mapping
SessionFactory sf = cfg.buildSessionFactory();
■Object identity—Objects are identical if they occupy the same memory location in the JVM. This can be checked by using the == operator.
■Object equality—Objects are equal if they have the same value, as defined by the equals(Object o) method. Classes that don’t explicitly override this method inherit the implementation defined by java.lang.Object, which compares object identity.
■Database identity—Objects stored in a relational database are identical if they represent the same row or, equivalently, share the same table and primary key value.
Hibernate has several built-in identifier generation strategies:
Tab Pag.114
<component
name=”homeAddress”
class=”Address”>
<parent name=”user”/>
<property name=”street” type=”string” column=”HOME_STREET”/>
<property name=”city” type=”string” column=”HOME_CITY”/>
<property name=”zipcode” type=”short” column=”HOME_ZIPCODE”/>
</component>
The <parent> element maps a property of type User to the owning entity, in this example, the property is named user. We then call Address.getUser() to navigate in the other direction.
A Hibernate component may own other components and even associations to other entities. This flexibility is the foundation of Hibernate’s support for finegrained object models. There are two important limitations to classes mapped as components:
■Shared references aren’t possible. The component Address doesn’t have its own database identity (primary key) and so a particular Address object can’t be referred to by any object other than the containing instance of User.
â– There is no elegant way to represent a null reference to an Address. Hibernate represents null components as null values in all mapped columns of the component. This means that if you store a component object with all null property values, Hibernate will return a null component when the owning entity object is retrieved from the database.
Mapping
Table per concrete class
We could use exactly one table for each (non-abstract) class. The main problem with this approach is that it doesn’t support polymorphic associations very well. (can’t be represented as a simple foreign key relationship.)
Table per class hierarchy
Alternatively, an entire class hierarchy could be mapped to a single table. This table would include columns for all properties of all classes in the hierarchy. There is one major problem: Columns for properties declared by subclasses must be declared to be nullable. If your subclasses each define several non-nullable properties, the loss of NOT NULL constraints could be a serious problem from the point of view of data integrity.
[ The <discriminator> element is required for polymorphic persistence using the table-per-class-hierarchy mapping strategy. It declares a discriminator column of the table. The discriminator column contains marker values that tell the persistence layer what subclass to instantiate for a particular row. A restricted set of types can be used: string, character, integer, byte, short, boolean, yes_no, true_false. ]
Table per subclass
The third option is to represent inheritance relationships as relational foreign key associations. Every subclass that declares persistent properties—including abstract, classes and even interfaces—has its own table.
The primary advantage of this strategy is that the relational model is completely normalized. Schema evolution and integrity constraint definition are straightforward. A polymorphic association to a particular subclass may be represented as a foreign key pointing to the table of that subclass. In Hibernate, we use the <joined-subclass> element to indicate a table-per-subclass mapping.
<?xml version=”1.0″?>
<hibernate-mapping>
<class name=”BillingDetails” table=”BILLING_DETAILS”>
<id name=”id” column=”BILLING_DETAILS_ID” type=”long”>
<generator class=”native”/>
</id>
<property name=”owner” column=”OWNER” type=”string”/>
…
<joined-subclass
name=”CreditCard”
table=”CREDIT_CARD”>
<key column=”CREDIT_CARD_ID”>
<property name=”type” column=”TYPE”/>
…
</joined-subclass>
…
</class>
</hibernate-mapping>
(Association (1-n, n-m, 1-1) dal sito)
To remodel the Item to Bid association as a parent/child relationship, the only change we need to make is to the cascade attribute:
<class name=”Item” table=”ITEM”>
…
<set name=”bids” inverse=”true” cascade=”all-delete-orphan”>
<key column=”ITEM_ID”/>
<one-to-many class=”Bid”/>
</set>
</class>
CASCADE
1) cascade=”none”, the default, tells Hibernate to ignore the association.
2) cascade=”save-update” tells Hibernate to navigate the association when the transaction is committed and when an object is passed to save() or update() and save newly instantiated transient instances and persist changes to detached instances.
3) cascade=”delete” tells Hibernate to navigate the association and delete persistent instances when an object is passed to delete().
4) cascade=”all” means to cascade both save-update and delete, as well as calls to evict and lock.
5) cascade=”all-delete-orphan” means the same as cascade=”all” but, in addition, Hibernate deletes any persistent entity instance that has been removed (dereferenced) from the association (for example, from a collection).
6) cascade=”delete-orphan” Hibernate will delete any persistent entity instance that has been removed (dereferenced) from the association (for example, from a collection).
Cap4.
The application must interact with the persistence layer whenever it needs to propagate state held in memory to the db or vice versa.
PAG 164
ORM OBJECT RELATIONAL MAPPING
It mapping between the objects and the database.ORM, in essence, works by (reversibly) transforming data from one representation to another.
CRUD (create, read, update, delete) operations
– Dati persistent
– Operation:
â– Storage, organization, and retrieval of structured data
â– Concurrency and data integrity
â– Data sharing
– GranularitÃ
If one application holds a lock on a database object, another application might not be able to access that object. For this reason, row-level locks, which minimize the amount of data that is locked and therefore inaccessible, are better for maximum concurrency than block-level, data partition-level or table-level locks. However, locks require storage and processing time, so a single table lock minimizes lock overhead.
The LOCKSIZE clause of the ALTER TABLE statement specifies the scope (granularity) of locks at the row, data partition, block, or table level. By default, row locks are used. Only S (Shared) and X (Exclusive) locks are requested by these defined table locks. The ALTER TABLE statement LOCKSIZE ROW clause does not prevent normal lock escalation from occurring.
A permanent table lock defined by the ALTER TABLE statement might be preferable to a single-transaction table lock using LOCK TABLE statement in the following cases:
– The table is read-only, and will always need only S locks. Other users can also obtain S locks on the table.
– The table is usually accessed by read-only applications, but is sometimes accessed by a single user for brief maintenance, and that user requires an X lock. While the maintenance program runs, the read-only applications are locked out, but in other circumstances, read-only applications can access the table concurrently with a minimum of locking overhead.
PAG 52
Cap2.
The persistence consists in storing data in a relational database using SQL. Hibernate applications define persistent classes that are “mapped†to database tables.
package hello;
public class Message {
private Long id;
private String text;
private Message nextMessage;
private Message() {
}
public Message(String text) {
this.text = text;
}
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
public String getText() {
return text;
}
}
public void setText(String text) {
this.text = text;
}
public Message getNextMessage() {
return nextMessage;
}
public void setNextMessage(Message nextMessage) {
this.nextMessage = nextMessage;
}
}
It prints “Hello World” to the console.
Message message = new Message(“Hello World”);
System.out.println( message.getText() );
Our persistent class can be used in any execution context at all. Of course, you came here to see Hibernate itself, so let’s save a new Message to the database:
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
Message message = new Message(“Hello World”);
session.save(message);
tx.commit();
session.close();
This code calls the Hibernate Session and Transaction interfaces. It results in the execution of something similar to the following SQL:
insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)
values (1, ‘Hello World’, null)
We can also assume that the MESSAGES table already exists.
Session newSession = getSessionFactory().openSession();
Transaction newTransaction = newSession.beginTransaction();
List messages = newSession.find(“from Message as m order by m.text asc”);
//
HIBERNATE QUERY:
select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID
from MESSAGES m
order by m.MESSAGE_TEXT asc
//
System.out.println( messages.size() + ” message(s) found:” );
for ( Iterator iter = messages.iterator(); iter.hasNext(); ) {
Message message = (Message) iter.next();
System.out.println( message.getText() );
}
newTransaction.commit();
newSession.close();
All SQL is generated at runtime.
XML MAPPING HIBERNATE CODE
<?xml version=”1.0″?>
<!DOCTYPE hibernate-mapping PUBLIC
“-//Hibernate/Hibernate Mapping DTD//EN”
“http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd”>
<hibernate-mapping>
<class
name=”hello.Message”
table=”MESSAGES”>
<id name=”id” column=”MESSAGE_ID”>
<generator class=”increment”/>
</id>
<property name=”text” column=”MESSAGE_TEXT”/>
<many-to-one name=”nextMessage” cascade=”all” column=”NEXT_MESSAGE_ID”/>
</class>
</hibernate-mapping>
The Hibernate interfaces may be approximately classified as follows:
â– Interfaces called by applications to perform basic CRUD and querying operations. These interfaces are the main point of dependency of application business/control logic on Hibernate. They include Session, Transaction, and Query.
â– Interfaces called by application infrastructure code to configure Hibernate, most importantly the Configuration class.
â– Callback interfaces that allow the application to react to events occurring inside Hibernate, such as Interceptor, Lifecycle, and Validatable.
■Interfaces that allow extension of Hibernate’s powerful mapping functionality, such as UserType, CompositeUserType, and IdentifierGenerator. These interfaces are implemented by application infrastructure code (if necessary).
• SESSION
The Session interface is the primary interface used by Hibernate applications. Hibernate sessions are not thread safe and should by design be used by only one thread at a time.
• SESSION FACTORY
It’s intended to be shared among many application threads. There is typically a single SessionFactory for the whole application. However, if your application accesses multiple databases using Hibernate, you’ll need a SessionFactory for each database. The SessionFactory caches generated SQL statements and other mapping metadata that Hibernate uses at runtime.
The following code starts Hibernate:
Configuration cfg = new Configuration();
cfg.addResource(“hello/Message.hbm.xml”);
cfg.setProperties( System.getProperties() );
SessionFactory sessions = cfg.buildSessionFactory();
The location of the mapping file, Message.hbm.xml, is relative to the root of the application classpath.
If we had another persistent class, it would be defined in its own mapping file. You can load multiple mapping files by calling addResource() as often as you have to. Alternatively, if you follow the convention just described, you can use the method addClass(), passing a persistent class as the parameter:
SessionFactory sessions = new Configuration()
.addClass(org.hibernate.auction.model.Item.class)
.addClass(org.hibernate.auction.model.Category.class)
.addClass(org.hibernate.auction.model.Bid.class)
.setProperties( System.getProperties() )
.buildSessionFactory();
If another SessionFactory is needed—if there are multiple databases, for example—you repeat the process.
To specify configuration options, you may use any of the following techniques:
â– Used except for quick testing and prototypes:
â– Pass an instance of java.util.Properties to Configuration.setProperties().
â– Set system properties using java -Dproperty=value.
â– Place a file called hibernate.properties in the classpath.
â– Include <property> elements in hibernate.cfg.xml in the classpath.
• CONFIGURATION
The Configuration object is used to configure and bootstrap Hibernate. The application uses a Configuration instance to specify the location of mapping documents and Hibernate-specific properties and then create the SessionFactory.
Configuration in non-managed environment:
Java applications should use a pool of JDBC connections. There are three reasons for using a pool:
â– Acquiring a new connection is expensive.
â– Maintaining many idle connections is expensive.
â– Creating prepared statements is also expensive for some drivers.
hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://localhost/auctiondb
hibernate.connection.username = auctionuser
hibernate.connection.password = secret
hibernate.dialect = net.sf.hibernate.dialect.PostgreSQLDialect
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=300
hibernate.c3p0.max_statements=50
hibernate.c3p0.idle_test_period=3000
Specifying properties of the form hibernate.c3p0.* selects C3P0 as Hibernate’s connection pool.
Configuration managed environment:
A managed environment handles certain cross-cutting concerns, such as application security (authorization and authentication), connection pooling, and transaction management.
hibernate.connection.datasource = java:/comp/env/jdbc/AuctionDB
hibernate.transaction.factory_class =
net.sf.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class =
net.sf.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = net.sf.hibernate.dialect.PostgreSQLDialect
XML-based Configuration:
The hibernate.cfg.xml file may also specify the location of mapping documents.
?xml version=’1.0’encoding=’utf-8′?>
<!DOCTYPE hibernate-configuration
PUBLIC “-//Hibernate/Hibernate Configuration DTD//EN”
“http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd”>
<hibernate-configuration>
<session-factory name=”java:/hibernate/HibernateFactory”>
<property name=”show_sql”>true</property>
<property name=”connection.datasource”> java:/comp/env/jdbc/AuctionDB</property>
<property name=”dialect”> net.sf.hibernate.dialect.PostgreSQLDialect </property>
<property name=”transaction.manager_lookup_class”>
net.sf.hibernate.transaction.JBossTransactionManagerLookup
</property>
<mapping resource=”auction/Item.hbm.xml”/>
<mapping resource=”auction/Category.hbm.xml”/>
<mapping resource=”auction/Bid.hbm.xml”/>
</session-factory>
</hibernate-configuration>
Now you can initialize Hibernate using:
SessionFactory sessions = new Configuration() .configure().buildSessionFactory();
When configure() was called, Hibernate searched for a file named hibernate.cfg.xml in the classpath. If you wish to use a different filename or have Hibernate look in a subdirectory, you must pass a path to the configure() method:
SessionFactory sessions =
new Configuration().configure(“/hibernate-config/auction.cfg.xml”).buildSessionFactory();
Using an XML configuration file is certainly more comfortable than a properties file or even programmatic property configuration.
Logging
When you find yourself troubleshooting a difficult problem, you need to be able to see exactly what’s going on inside Hibernate. You can use logging to get a view of Hibernate’s internals. Hibernate logs all interesting events using Apache commons-logging, a thin abstraction layer that directs output to either Apache log4j (if you put log4j.jar in your classpath).
JNDI
è acronimo di Java Naming and Directory Interface. All’interno di un Application Server (e anche in applicazioni non necessariamente web). Tutte le operazioni fondamentali che si possono compiere in un Application Server possono essere rimappate utilizzando JNDI. Elenchiamo alcune delle principali operazioni che normalmente vengono compiute: Transazioni (UserTransaction & TransactionManager) Pool di Connessioni ai Database (Datasource) Pool di Connessioni Transazionali ai Database (XADatasource). Con JNDI si possono rimappare tutti i percorsi fisici a cui è necessario puntare, in una sorta di tabella chiave-valore, una specie di HashTable, che rende facilmente configurabile, e quindi portabile, la nostra applicazione. Per maggiori informazioni ed esempi vi invito caldamente a visitare i link correlati. In particolare nel primo link è mostrato come accedere a JNDI in un Application Server Bea Weblogic.
Finally, you have the hibernate.properties, hibernate.cfg.xml, and log4j.properties configuration files.
Or
JMX: JAVA MANAGEMENT EXTENSION
The JMX specification defines the following components:
■The JMX MBean—A reusable component (usually infrastructural) that exposes an interface for management (administration)
■The JMX container—Mediates generic access (local or remote) to the MBean
■The (usually generic) JMX client—May be used to administer any MBean via the JMX container
An application server with support for JMX (such as JBoss) acts as a JMX container and allows an MBean to be configured and initialized as part of the application server startup process.
<server>
<mbean code=”net.sf.hibernate.jmx.HibernateService” name=”jboss.jca:service=HibernateFactory, name=HibernateFactory”>
<depends>jboss.jca:service=RARDeployer</depends>
<depends>jboss.jca:service=LocalTxCM, name=DataSource</depends>
<attribute name=”MapResources”> auction/Item.hbm.xml, auction/Bid.hbm.xml </attribute>
<attribute name=”JndiName”> java:/hibernate/HibernateFactory </attribute>
<attribute name=”Datasource”> java:/comp/env/jdbc/AuctionDB </attribute>
<attribute name=”Dialect”> net.sf.hibernate.dialect.PostgreSQLDialect </attribute>
<attribute name=”TransactionStrategy”> net.sf.hibernate.transaction.JTATransactionFactory </attribute>
<attribute name=”TransactionManagerLookupStrategy”> net.sf.hibernate.transaction.JBossTransactionManagerLookup </attribute>
<attribute name=”UserTransactionName”> java:/UserTransaction </attribute>
</mbean>
</server>
• TRANSICTION
The Transaction interface is an optional API. Hibernate applications may choose not to use this interface, instead managing transactions in their own infrastructure code. A Transaction abstracts application code from the underlying transaction implementation allowing the application to control transaction boundaries via a consistent API.
• CALLBACK
Callback interfaces allow the application to receive a notification when something interesting happens to an object—for example, when an object is loaded, saved, or deleted. Hibernate applications don’t need to implement these callbacks, but they’re useful for implementing certain kinds of generic functionality, such as creating audit records. The Lifecycle and Validatable interfaces allow a persistent object to react to events relating to its own persistence lifecycle.
• TYPE
A Hibernate Type object maps a Java type to a database column type (actually, the type may span multiple columns). All persistent properties of persistent classes, including associations, have a corresponding Hibernate type. This design makes Hibernate extremely flexible and extensible.
• EXTENSION POINTS:
â– Primary key generation (IdentifierGenerator interface)
â– SQL dialect support (Dialect abstract class)
////Serve e a specificare quale database stiamo utilizzando oracledialect; mysqldialect ecc…
â– Caching strategies (Cache and CacheProvider interfaces)
â– JDBC connection management (ConnectionProvider interface)
â– Transaction management (TransactionFactory, Transaction, and TransactionManagerLookup interfaces)
â– ORM strategies (ClassPersister interface hierarchy)
â– Property access strategies (PropertyAccessor interface)
â– Proxy creation (ProxyFactory interface)
http://www.roseindia.net/hibernate/firstexample.shtml
ARCHITETTURA:
Session, Transaction, and Query
(Create and compile a persistent class (the initial Message, for example), copy Hibernate and its required libraries to the classpath together with a hibernate.properties file, and build a SessionFactory. The next section covers advanced Hibernate configuration options. Some of them are recommended, such as logging executed SQL statements for debugging or using the convenient XML configuration file instead of plain properties.)
Cap3.
You shouldn’t put code that addresses these cross-cutting concerns in the classes that implement the domain model. When these concerns start to appear in the domain model classes, we call this an example of leakage of concerns. The EJB standard tries to solve the problem of leaky concerns. Indeed, if we implemented our domain model using entity beans, the container would take care of some concerns for us (or at least externalize those concerns to the deployment descriptor). The EJB container prevents leakage of certain cross-cutting concerns using interception. An EJB is a managed component, always executed inside the EJB container. The container intercepts calls to your beans and executes its own functionality. Hibernate isn’t an application server, and it doesn’t try to implement all the cross-cutting concerns mentioned in the EJB specification. Hibernate is a solution for just one of these concerns: persistence. If you require declarative security and transaction management, you should still access your domain model via a session bean, taking advantage of the EJB container’s implementation of these concerns. Hibernate is commonly used together with the well-known session façade J2EE pattern. Much discussion has gone into the topic of persistence, and both Hibernate and EJB entity beans take care of that concern. However, Hibernate offers something that entity beans don’t: transparent persistence. Our Item class, for example, will not have any code-level dependency to any Hibernate API. Furthermore:
■Hibernate doesn’t require that any special superclasses or interfaces be inherited or implemented by persistent classes. Nor are any special classes used to implement properties or associations. Thus, transparent persistence improves code readability, as you’ll soon see.
â– Persistent classes may be reused outside the context of persistence, in unit tests or in the user interface (UI) tier, for example. Testability is a basic requirement for applications with rich domain models.
■In a system with transparent persistence, objects aren’t aware of the underlying data store; they need not even be aware that they are being persisted or retrieved. Persistence concerns are externalized to a generic persistence manager interface —in the case of Hibernate, the Session and Query interfaces.
By this definition of transparent persistence, you see that certain non-automated persistence layers are transparent (for example, the DAO pattern) because they decouple the persistence-related code with abstract programming interfaces.
The programming model we’ll introduce is a non-intrusive mix of JavaBean specification details, POJO best practices, and Hibernate requirements. A POJO declares business methods, which define behavior, and properties, which represent state. Some properties represent associations to other POJOs. It’s an implementation of the User entity of our domain model.
public class User implements Serializable {
private String username;
private Address address;
public User() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Address getAddress() {
return address;
public void setAddress(Address address) {
this.address = address;
}
…
}
}
You use properties to express associations between POJO classes, and you use accessor methods to navigate the object graph at runtime.
scaffolding code:codice di “collegamentoâ€(ER model).
For example let’s implement the scaffolding code for the one-to-many self-association of Category:
public class Category implements Serializable {
private String name;
private Category parentCategory;
private Set childCategories = new HashSet();
public Category() { }
…
}
To allow bidirectional navigation of the association, we require two attributes. The parentCategory attribute implements the single-valued end of the association and is declared to be of type Category. The many-valued end, implemented by the child-Categories attribute, must be of collection type. We choose a Set, since duplicates are disallowed, and initialize the instance variable to a new instance of HashSet. We now have some private instance variables but no public interface to allow access from business code or property management by Hibernate. Let’s add some accessor methods to the Category class:
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set getChildCategories() {
return childCategories;
}
public void setChildCategories(Set childCategories) {
this.childCategories = childCategories;
}
public Category getParentCategory() {
return parentCategory;
}
public void setParentCategory(Category parentCategory) {
this.parentCategory = parentCategory;
}
Again, these accessor methods need to be declared public only if they’re part of the external interface of the persistent class, the public interface used by the application logic. The basic procedure for adding a child Category to a parent Category looks like this:
Category aParent = new Category();
Category aChild = new Category();
aChild.setParentCategory(aParent);
aParent.getChildCategories().add(aChild);
â– The parentCategory of the child must be set, effectively breaking the association between the child and its old parent (there can be only one parent for any child).
â– The child must be added to the child Categories collection of the new parent.
Programming models like EJB entity beans muddle this behavior by introducing container-managed relationships. The container automatically changes the other side of a relationship if one side is modified by the application.
Hibernate doesn’t care if property access methods are private or public, so we can focus on good API design.
One of the reasons we like to use JavaBeans-style access methods is that they provide encapsulation: The hidden internal implementation of a property can be changed without any changes to the public interface. This allows you to abstract the internal data structure of a class—the instance variables—from the design of the database. For example, if your database stores a name of the user as a single NAME column, but your User class has first name and last name properties, you can add the following persistent name property to your class:
Public class User {
private String firstname;
private String lastname;
…
public String getName() {
return firstname + ‘ ‘ + lastname;
}
public void setName(String name) {
StringTokenizer t = new StringTokenizer(name);
firstname = t.nextToken();
lastname = t.nextToken();
)
…
}
Later, you’ll see that a Hibernate custom type is probably a better way to handle many of these kinds of situations.
Hibernate will later use our accessor methods to populate the state of an object when loading the object from the database. Hibernate result in unnecessary SQL UPDATEs.
This kind of code should almost always be avoided in accessor methods:
public void setNames(List namesList) {
names = (String[]) namesList.toArray();
}
public List getNames() {
return Arrays.asList(names);
}
METADATA
ORM tools require a metadata format for the application to specify the mapping between classes and tables, properties and columns, associations and foreign keys, Java types and SQL types. This information is called the object/relational mapping metadata. It defines the transformation between the different data type systems and relationship representations.
XML mapping:
(DTD = document type definition)
<?xml version=”1.0″?>
<!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD//EN”
“http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd”>
<hibernate-mapping>
<class name=”org.hibernate.auction.model.Category” table=”CATEGORY”>
<id name=”id” column=”CATEGORY_ID” type=”long”>
<generator class=”native”/>
</id>
<property name=”name” column=”NAME” type=”string”/>
</class>
</hibernate-mapping>
If you omit the type, Hibernate will use the Hibernate type string by default. The <property> element (and especially the <column> element) also defines certain attributes that apply mainly to automatic database schema generation.
<property name=”initialPrice” column=”INITIAL_PRICE” not-null=”true”/>
<property name=”totalIncludingTax”
formula=”TOTAL + TAX_RATE * TOTAL”
type=”big_decimal”/>
The given SQL formula is evaluated every time the entity is retrieved from the database. The property doesn’t have a column attribute (or sub-element) and appears in an SQL SELECTs. Formulas may refer to columns of the database table, call SQL functions, and include SQL subselects. This example, mapping a derived property of item, uses a correlated subselect to calculate the average amount of all bids for an item:
<property name=”averageBidAmount”
formula=”( select AVG(b.AMOUNT)
from BID b
âž¾where b.ITEM_ID = ITEM_ID )”
type=”big_decimal”/>
access=”field”
Access to properties via accessor methods is considered best practice by the Hibernate community. It provides an extra level of abstraction between the Java domain model and the data model.
insert=”false”
update=”false”
The property name of the JavaBean is therefore immutable and can be read from the database but not modified in any way. If the complete class is immutable, set the immutable=”false” in the class mapping. The dynamic-update attribute tells Hibernate whether to include unmodified properties in the SQL UPDATE:
<class name=”org.hibernate.auction.model.User”
dynamic-insert=”true”
dynamic-update=”true”>
…
</class>
These are both class-level settings. Enabling either of these settings will cause Hibernate to generate some SQL at runtime, instead of using the SQL cached at startup time.
SQL schemas
You can specify a default schema using the hibernate.default_schema configuration option. Alternatively, you can specify a schema in the mapping document. A schema may be specified for a particular class or collection mapping:
<hibernate-mapping>
<class
name=”org.hibernate.auction.model.Category”
table=”CATEGORY”
schema=”AUCTION”>
…
</class>
</hibernate-mapping>
It can even be declared for the whole document:
<hibernate-mapping
default-schema=”AUCTION”>
..
</hibernate-mapping>
This isn’t the only thing the root <hibernate-mapping> element is useful for.
( http://www.mokabyte.it/2005/11/hibernate.htm
tag of XDOCLET:
http://xdoclet.sourceforge.net/xdoclet/tags/hibernate-tags.html#@hibernate_property__0__1_
using a script build.xml of Ant )
using declaration type
…
// Define a new column for the USER table
Column column = new Column();
column.setType(Hibernate.STRING);
column.setName(“ETA”);
column.setNullable(false);
column.setUnique(true);
userMapping.getTable().addColumn(column);
// Wrap the column in a Value
SimpleValue value = new SimpleValue();
value.setTable( userMapping.getTable() );
value.addColumn(column);
value.setType(Hibernate.STRING);
// Define a new property of the User class
Property prop = new Property();
prop.setValue(value);
prop.setName(“eta”);
userMapping.addProperty(prop);
// Build a new session factory, using the new mapping
SessionFactory sf = cfg.buildSessionFactory();
■Object identity—Objects are identical if they occupy the same memory location in the JVM. This can be checked by using the == operator.
■Object equality—Objects are equal if they have the same value, as defined by the equ
-
AuthorPosts