1. Trang chủ
  2. » Công Nghệ Thông Tin

Beginning Hibernate From Novice to Professional phần 9 potx

35 262 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 35
Dung lượng 545,78 KB

Nội dung

T ransaction tx = session.beginTransaction(); // Make our bookings s ession.save(new Booking("dave","F1")); session.save(new Booking("jeff","C3")); // The confirmation letters should not be sent // out until AFTER the commit completes. tx.commit(); } } The interceptor that we are applying is going to capture the information from the Booking objects that we are storing in the database. Listing A-26 demonstrates the basic mechanism, but it is only a toy example. We will discuss some of its deficiencies in a moment. Listing A-26. An Interceptor Implementation package com.hibernatebook.advanced.events; import java.io.Serializable; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import org.hibernate.CallbackException; import org.hibernate.EntityMode; import org.hibernate.Interceptor; import org.hibernate.Transaction; import org.hibernate.type.Type; public class BookingInterceptor implements Interceptor { public BookingInterceptor() { } private ThreadLocal stored = new ThreadLocal(); public void afterTransactionBegin(Transaction tx) { stored.set(new HashSet()); } public void afterTransactionCompletion(Transaction tx) { if (tx.wasCommitted()) { Iterator i = ((Collection) stored.get()).iterator(); APPENDIX A ■ MORE ADVANCED FEATURES 259 6935appA_final.qxd 8/2/06 9:18 PM Page 259 w hile (i.hasNext()) { Booking b = (Booking) i.next(); sendMail(b); } } stored.set(null); } public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException { ((Collection) stored.get()).add(entity); return false; } private void sendMail(Booking b) { // Here we would actually send out the e-mail System.out.print("Name: " + b.getName()); System.out.println(", Seat: " + b.getSeat()); } public void beforeTransactionCompletion(Transaction tx) { } public int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) { return null; } public Object getEntity(String entityName, Serializable id) throws CallbackException { return null; } public String getEntityName(Object object) throws CallbackException { return null; } public Object instantiate(String entityName, EntityMode entityMode, Serializable id) throws CallbackException { return null; } public Boolean isTransient(Object object) { return null; } APPENDIX A ■ MORE ADVANCED FEATURES260 6935appA_final.qxd 8/2/06 9:18 PM Page 260 p ublic void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException { } public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) throws CallbackException { return false; } public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException { return false; } public void postFlush(Iterator entities) throws CallbackException { } public void preFlush(Iterator entities) throws CallbackException { } } Our interceptor makes use of the afterTransactionBegin() method to prepare to collect booking details, the onSave() method to collect them, and the afterTransactionCompletion() method to report the successful bookings. This sequence guarantees that bookings will not be reported to the users until after we are confident that they have been retained in the database. A minor deficiency of this implementation is that the e-mail is sent outside the transac- tion—a system failure immediately after the commit completes could cause the e-mail not to be sent. In our scenario, this is unimportant, because e-mail is already an unreliable transport mechanism; but there are other situations, such as the auditing example discussed earlier, in which this may be unacceptable. In these cases, interception may not be appropriate, and an integrated solution tied into a two-phase commit transaction may be required. More importantly, our example assumes that the Booking object will not be altered between its addition to the set of e-mails to be sent and their transmission. This is an extremely danger- ous assumption! A safer approach would be to create copies of the Booking objects or, better yet, to cop y their data into a more appropriate object, as shown in Listing A-27. Listing A-27. A B etter Approach to Preparing the Mailshot public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException { if( entity instanceof Booking ) { Booking booking = (Booking)entity. Mailshot mailshot = new Mailshot(booking.getName(), booking.getSeat() ); APPENDIX A ■ MORE ADVANCED FEATURES 261 6935appA_final.qxd 8/2/06 9:18 PM Page 261 ( (Collection) stored.get()).add(mailshot); } return false; } F inally, we don’t necessarily have enough information to prepare our mailshot—the e-mail address may be missing. If the name field actually represents the e-mail address, then we are fine; but if it represents a key into other objects, and hence tables in the database, then we have to be careful. It is possible to write database logic from within an interceptor, but the risk of accidentally recursing back into your interceptor logic is high, so we don’t recommend it. It’s slightly less tricky if you are only using a session-scoped interceptor, but there are prob- ably safer ways to achieve the same end result. In this example, the methods that we are not using have been given a default implemen- tation. You will note that some of these methods return null or false. These methods are permitted to change the data that is preserved or returned by the session. Returning to the onSave() method, we will consider another possible implementation, shown in Listing A-28. Listing A-28. Changing the Data from Within an Interceptor public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException { if( entity instanceof Booking ) { state[1] = "unknown"; } return true; } Here we are altering the state array. This contains the values of each of the objects’ fields that are to be stored (in the order defined in the mapping file). In our Booking class, field 0 is the id, field 1 is the name, and field 2 is the seat—so here we have changed the name value to be pre- served in the database. Returning true causes Hibernate to reflect this change when it saves the data. If we left the return flag as false, nothing would happen when the method was called. The temptation is to assume that returning false guarantees the safety of the data to be preserved, but, in fact, this is not the case. The state array represents copies of the data to be preserved—but we have also been given access to the actual object (entity) that contains the original values. If you amend the fields of the entity before returning, the flag will not pre- v ent y our changes fr om being made . Listing A-29 illustrates how this might occur. Listing A-29. Changing the Data in an Unorthodox Way public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException APPENDIX A ■ MORE ADVANCED FEATURES262 6935appA_final.qxd 8/2/06 9:18 PM Page 262 { if( entity instanceof Booking ) { Booking booking = (Booking)entity; b ooking.setName("unknown"); } // The flag can't save us from ourselves here! return false; } Again, this is probably not the best way to make the changes, but it can be useful when you already have a considerable body of logic prepared to process the entity type. Overriding the Default Constructor Occasionally, you will find that it is necessary to persist a POJO that has no default constructor. Usually you will have access to the source code, and should just make the change directly. Occa- sionally, however, you may find that you are working with classes for which the source code is not available—or that you are working with large bodies of generated objects for which it is extremely inconvenient to manage changes made to the source code. In these circumstances, it is possible to use an interceptor to replace the default object-creation logic. This technique can be used as long as you have some way of obtaining or applying default values for the parameters of the POJO’s non-default constructor. Listing A-30 shows an exam- ple of the use of this technique to instantiate a POJO whose only constructor demands a String parameter. Listing A-30. Invoking a Non-Default Constructor private static class OverrideCtor implements Interceptor { public Object instantiate( String entityName, EntityMode entityMode, Serializable id) throws CallbackException { if( entityName.equals(MissingDefaultCtorClass.class.getName())) { // My call to CTor return new MissingDefaultCtorClass("NOT SET"); } else { // Some other class - continue to default handling return null; } } // the remaining default method declarations } APPENDIX A ■ MORE ADVANCED FEATURES 263 6935appA_final.qxd 8/2/06 9:18 PM Page 263 Summary In this appendix, we have examined Hibernate’s place in the new Enterprise Java Beans stan- dard (EJB 3), and looked at alternative mechanisms for accessing Hibernate entities. We have shown how SQL and stored procedures can be integrated into the Hibernate environment, and we have discussed how events and listeners provide internal access to Hibernate’s per- sistence mechanism. APPENDIX A ■ MORE ADVANCED FEATURES264 6935appA_final.qxd 8/2/06 9:18 PM Page 264 Hibernate Tools The Hibernate Tools toolset really consists of two quite distinct tools: a set of plug-ins to enhance the Eclipse integrated development environment (IDE), and a set of tasks for the Ant build tool. They are packaged together because they share significant chunks of imple- mentation despite their very different façades. We have already used one of the Ant tasks from Hibernate Tools in earlier chapters to generate our database schemas. In this appendix, we will discuss the other available tasks. First, however, we will discuss the use of the toolset as a plug-in for Eclipse. ■Caution At the time of writing, Hibernate Tools is at an advanced beta stage of development. You should be a ware that you may encounter rough edges and bugs when using these tools. Currently, the Ant tasks are more polished than the Eclipse plug-ins. Even so, we think that it is well worth familiarizing yourself with all these tools and even using them in production, as most of the problems can be worked around. It is beyond the scope of this book to attempt to teach you how to use Ant or Eclipse (although we do walk you through some of the less common configuration details). To get the most from this appendix, you should be familiar with both Ant and Eclipse—although it is possible to use both parts of the plug-in independently. General information on the latest versions of Hibernate Tools, any changes or new fea- tur es, the online documentation, and the locations of the various downloads are available from the Hibernate web site (http://tools.hibernate.org). The Eclipse Plug-In Eclipse is one of the best-known and liked Java development environments to emerge in recent years. Eclipse evolved originally as a proprietary component of IBM’s WebSphere A pplication Developer (WSAD) environment. IBM chose to release Eclipse, the IDE, as an open source application. Thus, the open source Eclipse IDE emerged as a mature product virtually overnight. Eclipse is designed as a core application, the Eclipse platform, extended by various plug- ins, typically including Java Development Tools (JDT). For our purposes, we assume that you will start out with this combination (known rather confusingly as the Software Development 265 APPENDIX B ■ ■ ■ 6935appB_final.qxd 8/2/06 9:15 PM Page 265 Kit, or SDK) as the basis for installing Hibernate Tools. At the time of writing, the latest version of the SDK is 3.1.2. Eclipse can be downloaded from the Eclipse Foundation web site ( www.eclipse.org). You will find a file named eclipse-SDK-3.1.2-win32.zip in the Downloads section. The Hibernate team is now employed by JBoss, who provides a branded version of Eclipse that includes the Hibernate plug-ins, including several JBoss-specific ones. This can be down- loaded from the JBoss web site ( http://download.jboss.com/jbosside/builds). If you choose to use this version of Eclipse, then you can omit the installation steps described in the next section. Installing the Plug-In We will now walk you through the process of installing the plug-in using Eclipse’s standard updates feature. Select the Find and Install menu option from the Help ➤ Software Updates menu. You should then select the option to search for new features, as Hibernate is not a stan- dard Eclipse SDK component. By default, Eclipse will only be aware of the Eclipse Foundation web site as a source of new Eclipse features. Click the New Remote Site button shown in the upper right of Figure B-1 to add the site from which you will obtain the Hibernate Tools plug-in. Y ou will now need to enter the URL for the site fr om which Eclipse will obtain the plug-in, and an informal name for the site, into the dialog shown in Figure B-2. Presently, the down- load site is at http://download.jboss.org/jbosside/updates/development—this is unlikely to change , but if you encounter pr oblems, you should check the http://tools.hibernate.org web site to make sure that this is still listed as the update site. APPENDIX B ■ HIBERNATE TOOLS266 Figure B-1. By default, only www.eclipse.org is available as a download site. 6935appB_final.qxd 8/2/06 9:15 PM Page 266 You will then be returned to the list of sites shown in Figure B-3, where you should uncheck the Eclipse download site, as you will only be installing the Hibernate Tools plug-in. Click the Next button, and Eclipse will download the list of available updates from the updates site that you have provided. If you have not provided the correct site name, or you have other connectivity issues, you will not be able to reach this step. If you are experiencing problems, go back and check that you have configured any necessary proxy settings, and that all the appropriate URLs have been entered correctly. Once you successfully reach this step, you should select the Hibernate Tools check box and click Next. Eclipse now lists the features that will be installed and prompts you to accept the license that applies to the plug-in features. You must accept the terms and conditions of the license to proceed beyond this step. Once you have checked the Accept radio button, click the Next button. Y ou will now be presented confirmation of the features to be installed, and given the option of installing the features to a nonstandard location. (We always accept the default installation into the Eclipse plug-ins directory.) Click Finish to proceed. C urrently , the Hibernate Tools plug-in is not digitally signed. Eclipse warns you of this. In principle, it is possible that a malicious third party with access to servers between you and the Eclipse download site could substitute their own code for the Eclipse tools. In prac- tice this is unlikely , but it is to be hoped that the Hiber nate or JBoss teams will start code signing their final releases. To proceed with the plug-in installation, you must accept the verification prompt. F inally , E clipse prompts you to restart or apply the changes directly. Generally when installing Eclipse plug-ins, it is safest to select the restart option. Though we know of no spe- cific problems with the Hibernate Tools, we recommend choosing restart here anyway—it won’t be necessar y to reboot the PC, though! APPENDIX B ■ HIBERNATE TOOLS 267 Figure B-2. Specifying the new download site Figure B-3. Deselect the Eclipse update site. 6935appB_final.qxd 8/2/06 9:15 PM Page 267 At this point, you will have successfully completed the installation of the Hibernate Tools plug-in. There will be no immediate visible change to the layout of the workbench—however, as you will see in the next step, there should be some new options for you, accessible via the various menus—including a new Eclipse perspective onto some of the Hibernate workbench views. ■Note If you are unable or unwilling to install the software directly from Eclipse, it is also possible to download the tools as a ZIP file from the Hibernate site and copy the plug-ins directory from the archive directly over the top of Eclipse’s own plug-ins directory. You should then restart Eclipse for the changes to take effect. We do not recommend that you try this approach unless you are already comfortable with the process of installing Eclipse plug-ins in this manner. The Eclipse plug-in installation process is now quite streamlined, so it is unlikely that you will encounter any serious problems. However, if you do have problems, first check that you have the correct versions of the downloads described here, and check that you have followed the installation steps as given previously. If you are still encountering problems, you should search the Tools forum on the Hibernate Forums page ( http://forum.hibernate.org) to see if other users have encountered the same problems. You should also check the Hibernate bug database ( www.hibernate.org/217.html) to see if there are known problems that match yours. The Boilerplate Project Configuration Now that the tools plug-in has been installed, you are ready to set up a project that will take advantage of it. As a first step, we recommend configuring a user library to make adding the appropriate JAR files to new projects more straightforward, and to make the resulting project view less cluttered. Figure B-4 compares the view of the project’s contents with and without the use of user libraries. APPENDIX B ■ HIBERNATE TOOLS268 Figure B-4. A n Eclipse pr oject using user libr aries (left) compared with one using JAR files directly (right) 6935appB_final.qxd 8/2/06 9:15 PM Page 268 [...]... is imported into Ant using the standard TaskDef element This makes the Hibernate tools libraries available to Ant itself, and allows you to select an appropriate element representing the Hibernate tools to use in your script The Hibernate Tools JAR file must be made available to Ant on the classpath—our... exporter only, the destination directory specified on the tools task destdir ejb3 false If set to true, causes the POJOs to be generated with EJB 3 annotations jdk5 false If set to true, causes the POJOs to be generated with Java 5 constructs (generics, enumerations, etc.) 2 89 693 5appB_final.qxd 290 8/2/06 9: 15 PM Page 290 APPENDIX B s HIBERNATE TOOLS This exporter can be used to permit the mapping file–based... hibernate- mapping PUBLIC "-/ /Hibernate/ Hibernate Mapping DTD 3.0//EN" "http:/ /hibernate. sourceforge.net /hibernate- mapping-3.0.dtd"> < /hibernate- mapping> The Hibernate Tools plug-in for Eclipse includes an editor for its various mapping files that provides context-sensitive completion—this is based upon the Web Tools... tweaking it into working correctly Hibernate Tools now provides a query editor that allows you to prototype your HQL queries and run them against the database without needing to write any code To run an HQL query, select HQL Scratchpad from the context menu for the project in the configuration view (by default, this is to the left of the main window in the Hibernate Console perspective) A new editor window... sa org .hibernate. dialect.HSQLDialect < /hibernate- configuration> The Reverse Engineering and Code Generation Tools The last Hibernate Tools wizard is for the reverse engineering tool This allows you to extract the schema information from the database into an XML file Additional... classes can only be used to determine schema names from mapping information, not vice versa Hibernate provides two ways in which this process can be controlled—you can specify one of two attributes on the task to override the default behavior 291 693 5appB_final.qxd 292 8/2/06 9: 15 PM Page 292 APPENDIX B s HIBERNATE TOOLS The reversestrategy attribute allows you to specify the fully... … This outermost task element accepts three attributes, as listed in Table B-1 285 693 5appB_final.qxd 286 8/2/06 9: 15 PM Page 286 APPENDIX B s HIBERNATE TOOLS Table B-1 The Daughter Elements of the Hibernate Tools Task Attribute Description classpath The path to use when locating libraries and configuration files destDir The base directory (relative to. .. The view allows you to place the entities using the mouse or lay them out automatically You can zoom into or out of the view, and you can print its contents At the time of writing, this feature is quite primitive and is therefore of limited use 2 79 693 5appB_final.qxd 280 8/2/06 9: 15 PM Page 280 APPENDIX B s HIBERNATE TOOLS Generating a Mapping File Hibernate Tools provides a wizard to make the creation... hibernate- configuration PUBLIC "-/ /Hibernate/ Hibernate Configuration DTD 3.0//EN" "http:/ /hibernate. sourceforge.net /hibernate- configuration-3.0.dtd"> org.hsqldb.jdbcDriver 281 693 5appB_final.qxd 282 8/2/06 9: 15 PM Page 282 APPENDIX B s HIBERNATE TOOLS jdbc:hsqldb:file:exampledb;SHUTDOWN=true... you choose to use XML-based mappings, you can use the file attribute to specify the mapping file instead, or specify the paths to the mapping files in the Hibernate configuration entry used by the Hibernate Console Hibernate Tools provides a wizard to create the Hibernate configuration entry To use the wizard, select the File ® New ® Hibernate Console Configuration menu option, as shown in Figure B-8 . ADVANCED FEATURES264 693 5appA_final.qxd 8/2/06 9: 18 PM Page 264 Hibernate Tools The Hibernate Tools toolset really consists of two quite distinct tools: a set of plug-ins to enhance the Eclipse. specify the paths to the mapping files in the Hibernate configuration entry used by the Hibernate Console. Hibernate Tools provides a wizard to create the Hibernate configuration entry. To use the wizard,. it into working correctly. Hibernate Tools now provides a query editor that allows you to prototype your HQL queries and run them against the database without needing to write any code. To run

Ngày đăng: 09/08/2014, 14:20

TỪ KHÓA LIÊN QUAN