Siêu thị PDFTải ngay đi em, trời tối mất

Thư viện tri thức trực tuyến

Kho tài liệu với 50,000+ tài liệu học thuật

© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

manning Hibernate in Action phần 10 pdf
PREMIUM
Số trang
60
Kích thước
2.8 MB
Định dạng
PDF
Lượt xem
1981

manning Hibernate in Action phần 10 pdf

Nội dung xem thử

Mô tả chi tiết

Licensed to Jose Carlos Romero Figueroa <[email protected]>

Development processes 349

Good ORM software comes bundled with a set of tools, and so does Hibernate. In

this chapter, we’ll discuss the Hibernate toolset. These tools can automatically gen￾erate mapping metadata, SQL database schemas, and even Java POJO source code.

However, you have to use the right tool for your specific development process.

9.1 Development processes

In some projects, the development of a domain model is driven by developers ana￾lyzing the business domain in object-oriented terms. In others, it’s heavily influ￾enced by an existing relational data model: either a legacy database or a brand-new

schema designed by a professional data modeler.

Since different projects start from different points, we need to consider differ￾ent development scenarios and the different tools that may be used in each case.

An overview of the tools and the artifacts they use as source and output is shown in

figure 9.1. You may want to refer to this diagram while reading this chapter.

NOTE Note that AndroMDA, a tool that generates POJO source code from UML

diagram files, isn’t strictly considered part of the common Hibernate

toolset; hence we don’t discuss it in this chapter. See the community area

on the Hibernate website for more information about the Hibernate

modules in AndroMDA.

Before we begin looking closely at any of the particular tools you can use with

Hibernate, we’ll briefly survey the main scenarios and mention the tools that are

most appropriate to each.

Mapping

Metadata

Database

Schema

POJO

Java Source

SchemaExport

(hbm2ddl)

XDoclet

XML/XMI

AndroMDA

CodeGenerator

(hbm2java)

Middlegen

UML Model

Figure 9.1

Input and output of the tools

used for Hibernate development

Licensed to Jose Carlos Romero Figueroa <[email protected]>

350 CHAPTER 9

Using the toolset

9.1.1 Top down

In top-down development, you start with an existing Java domain model (ideally imple￾mented with POJOs/JavaBeans) and complete freedom with respect to the data￾base schema. You must create a mapping document—either manually using a text

editor (recommended is an IDE with XML auto-completion) or automatically using

XDoclet—and then let Hibernate’s hbm2ddl tool generate the database schema. In

the absence of an existing data model, this is the most comfortable development

style for most Java developers. You can even use the Hibernate tools to automati￾cally refresh the database schema on every application restart in development.

9.1.2 Bottom up

Conversely, bottom-up development begins with an existing database schema and data

model. In this case, the easiest way to proceed is to use Middlegen to generate

Hibernate mapping documents and then run the hbm2java tool and generate skel￾etal POJO persistent classes. You’ll usually have to enhance and modify the gener￾ated Hibernate mapping by hand, because not all class association details and Java￾specific meta-information can be automatically generated from an SQL schema.

9.1.3 Middle out (metadata oriented)

Neither Java classes (without XDoclet annotations) nor DDL schemas contain

enough information to be able to completely deduce an ORM. Hence, if you wish

to generate the Hibernate mapping document instead of writing it by hand, you’ll

need extra input from the user. In the case of XDoclet, this information is provided

by XDoclet attributes embedded in the source code. In the case of Middlegen, it’s

provided via the Middlegen GUI.

On the other hand, the mapping document does provide sufficient information

to completely deduce the DDL schema and to generate working JavaBeans. Fur￾thermore, the mapping document isn’t too verbose. So, you may prefer middle-out

development, where you begin with a handwritten Hibernate mapping document

and generate the DDL using hbm2ddl and Java classes using hbm2java.

9.1.4 Meet in the middle

The most difficult scenario combines existing Java classes and an existing rela￾tional schema. In this case, there is little that the Hibernate toolset can do to help.

It isn’t possible to map arbitrary Java domain models to a given schema, so this sce￾nario usually requires at least some refactoring of the Java classes, database

Licensed to Jose Carlos Romero Figueroa <[email protected]>

Automatic schema generation 351

schema, or both. The mapping document must almost certainly be written by hand

(although it might be possible to use XDoclet). This is an incredibly painful sce￾nario that is, fortunately, exceedingly rare.

9.1.5 Roundtripping

The notion of roundtripping is that any one of the three kinds of artifacts (Java

classes, mapping documents, database schema) should be sufficient to reproduce

the other two. Each tool should be completely reversible. You’ve already seen that

this isn’t the case. At the very least, you must add XDoclet annotations to the Java

classes. Worse, it’s never possible to fully reproduce the Java domain model or ORM

from only the database schema.

Nevertheless, the Hibernate team is attempting to achieve a slightly less ambi￾tious goal for the Hibernate toolset. Suppose you start with an existing database

schema. Then the following steps should reproduce this schema exactly, with min￾imal user intervention:

1 Use Middlegen to create a mapping document

2 Use hbm2java to generate annotated Java classes

3 Use XDoclet to regenerate the mapping document

4 Use hbm2ddl to generate the DDL

At the time of this writing, there is still work to be done before this approach works

perfectly, because it involves many different tools and metamodel conversions.

We’ll now look more closely at each of the tools we’ve mentioned, starting with

hbm2ddl. This tool is used to automatically generate SQL DDL from Hibernate map￾ping metadata. We assume that you’ve already created some POJO persistent classes

and the relevant Hibernate mappings and are now looking for a way to simplify the

creation of the schema in the database.

9.2 Automatic schema generation

Schemas for SQL-based database management systems are written in the SQL

DDL. This includes well-known statements such as CREATE and ALTER.

The tool used for the generation process is called hbm2ddl. Its class is

net.sf.hibernate.tool.hbm2ddl.SchemaExport; hence it’s also sometimes called

SchemaExport.

Licensed to Jose Carlos Romero Figueroa <[email protected]>

352 CHAPTER 9

Using the toolset

NOTE The Hibernate extensions package—You may have noticed that hbm2ddl

resides inside the main Hibernate distribution and isn’t packaged with

the other tools in HibernateExtensions. The Hibernate team decided

that hbm2ddl is much closer to the core functionality of Hibernate than

any of the other tools and should be bundled with Hibernate itself. In

addition, you can run hbm2ddl from an application to automatically gen￾erate a database schema at runtime. This ability is especially useful if

you’d like to initialize the database every time the application in develop￾ment restarts.

In Hibernate, the prerequisite for automatically generating SQL DDL is always a

Hibernate mapping metadata definition in XML. We assume that you’ve designed

and implemented your POJO classes and written mapping metadata, but you prob￾ably haven’t paid much attention to database-specific details (like table and col￾umn names).

Some special elements and attributes can be used in the mapping files; most of

them are relevant only for a customized schema. Hibernate tries to use sensible

defaults if you don’t specify your own names and strategies; however, be warned

that a professional DBA might not accept this default schema without manual

changes. Nevertheless, the defaults may be satisfactory for a development or pro￾totype environment.

9.2.1 Preparing the mapping metadata

In this example, we’ve marked up the mapping for the Item class with hbm2ddl-spe￾cific attributes and elements. These optional definitions integrate seamlessly with

the other mapping elements, as you can see in listing 9.1.

Listing 9.1 Additional elements in the Item mapping for SchemaExport

<class name="Item" table="ITEM">

<id name="id" type="string">

<column name="ITEM_ID" sql-type="char(32)"/> B

<generator class="uuid.hex"/>

</id>

<property name="name" type="string">

<column name="NAME"

not-null="true"

length="255"

index="IDX_ITEMNAME"/> C

</property>

<property name="description"

type="string"

Licensed to Jose Carlos Romero Figueroa <[email protected]>

Automatic schema generation 353

column="DESCRIPTION"

length="4000"/> D

<property name="initialPrice"

type="customtype.MonetaryAmount">

<column name="INITIAL_PRICE" check="INITIAL_PRICE > 0"/> E

<column name="INITIAL_PRICE_CURRENCY"/>

</property>

<set name="categories" table="CATEGORY_ITEM" cascade="none">

<key

<column="ITEM_ID" sql-type="char(32)"/> F

</key>

<many-to-many class="Category">

<column="CATEGORY_ID" sql-type="char(32)/>

</many-to-many>

</set>

...

</class>

B hbm2ddl automatically generates a VARCHAR typed column if a property (even the

identifier property) is of mapping type string. We know the identifier generator

uuid.hex always generates strings that are 32 characters long; so, we use a CHAR

SQL type and also set its size fixed at 32 characters. The nested <column> element

is required for this declaration because there is no attribute to specify the SQL

datatype on the <id> element.

C The column, not-null, and length attributes are also available on the <property>

element, but we want to create an additional index in the database, hence we

again use a nested <column> element. This index will speed our searches for items

by name. If we reuse the same index name on other property mappings, we can

create an index that includes multiple database columns. The value of this

attribute is also used to name the index in the database catalog.

D For the description field, we chose the lazy approach, using the attributes on the

<property> element instead of a <column> element. The DESCRIPTION column will

be generated as VARCHAR(4000).

E The custom user-defined type MonetaryAmount requires two database columns to

work with. We have to use the <column> element. The check attribute triggers the

creation of a check constraint; the value in that column must match the given arbi￾trary SQL expression. Note that there is also a check attribute for the <class> ele￾ment, which is useful for multicolumn check constraints.

Licensed to Jose Carlos Romero Figueroa <[email protected]>

354 CHAPTER 9

Using the toolset

F A <column> element can also be used to declare the foreign key fields in an associ￾ation mapping. Otherwise, the columns of our association table CATEGORY_ITEM

would be VARCHAR(32) instead of the more appropriate CHAR(32) type.

We’ve grouped all attributes relevant for schema generation in table 9.1; some of

them weren’t included in the previous Item mapping example.

Table 9.1 XML mapping attributes for hbm2ddl

Attribute Value Description

column string Usable in most mapping elements; declares the name of the SQL

column. hbm2ddl (and Hibernate’s core) defaults to the name of

the Java property) if the column attribute is omitted and no

nested <column> element is present. This behavior may be

changed by implementing a custom NamingStrategy; see the

section “Naming conventions” in chapter 3.

not-null true/false Forces the generation of a NOT NULL column constraint. Available

as an attribute on most mapping elements and also on the dedi￾cated <column> element.

unique true/false Forces the generation of a single-column UNIQUE constraint.

Available for various mapping elements.

length integer Can be used to define a "length" of a datatype. For example,

length="4000" for a string mapped property generates a

VARCHAR(4000) column. This attribute is also used to define

the precision of decimal types.

index string Defines the name of a database index that can be shared by mul￾tiple elements. An index on a single column is also possible. Only

available with the <column> element.

unique-key string Enables unique constraints involving multiple database columns.

All elements using this attribute must share the same constraint

name to be part of a single constraint definition. This is a <col￾umn> element-only attribute.

sql-type string Overrides hbm2ddl’s automatic detection of the SQL datatype;

useful for database specific data types. Be aware that this effec￾tively prevents database independence: hbm2ddl will automati￾cally generate a VARCHAR or VARCHAR2 (for Oracle), but it will

always use a declared SQL-type instead, if present. This attribute

can only be used with the dedicated <column> element.

foreign-key string Names a foreign-key constraint, available for <many-to-one>,

<one-to-one>, <key>, and <many-to-many> mapping ele￾ments. Note that inverse="true" sides of an association map￾ping won’t be considered for foreign key naming, only the non￾inverse side. If no names are provided, Hibernate generates

unique random names.

Tải ngay đi em, còn do dự, trời tối mất!