jinfeng_wang

G-G-S,D-D-U!

BlogJava 首页 新随笔 联系 聚合 管理
  400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks

package com.oreilly.hh;

import net.sf.hibernate.
*;
import net.sf.hibernate.cfg.Configuration;

import java.sql.Time;
import java.util.Date;

/**
 * Create sample data, letting Hibernate persist it for us.
 
*/

public class CreateTest {

    
public static void main(String args[]) throws Exception {
        
// Create a configuration based on the properties file we've put
        
// in the standard place.
        Configuration config = new Configuration();

        
// Tell it about the classes we want mapped, taking advantage of
        
// the way we've named their mapping documents.
        config.addClass(Track.class);

        
// Get the session factory we can use for persistence
        SessionFactory sessionFactory = config.buildSessionFactory();

        
// Ask for a session using the JDBC information we've configured
        Session session = sessionFactory.openSession();
        Transaction tx 
= null;
        
try {
            
// Create some data and persist it
            tx = session.beginTransaction();

            Track track 
= new Track("Russian Trance",
                                    
"vol2/album610/track02.mp3",
                                    Time.valueOf(
"00:03:30"), new Date(),
                                    (
short)0);
            session.save(track);

            track 
= new Track("Video Killed the Radio Star",
                              
"vol2/album611/track12.mp3",
                              Time.valueOf(
"00:03:49"), new Date(),
                              (
short)0);
            session.save(track); 
            
             track 
= new Track("Gravity's Angel",
                              
"vol2/album175/track03.mp3",
                               Time.valueOf(
"00:06:06"), new Date(),
                               (
short)0);
            session.save(track);

            
// We're done; make our changes permanent
            tx.commit();

        }
 catch (Exception e) {
            
if (tx != null{
                
// Something went wrong; discard all partial changes
                tx.rollback();
            }

            
throw e;
        }
 finally {
            
// No matter what, close the session
            session.close();
        }


        
// Clean up after ourselves
        sessionFactory.close();
    }

}



When it comes time to actually perform persistence, we ask the SessionFactory to open a Session for us (line 27), which establishes a JDBC connection to the database, and provides us with a context in which we can create, obtain, manipulate, and delete persistent objects. As long as the session is open, a connection to the database is maintained, and changes to the persistent objects associated with the session are tracked so they can be applied to the database when the session is closed. Conceptually you can think of a session as a 'large scale transaction' between the persistent objects and the database, which may encompass several database-level transactions. Like a database transaction, though, you should not think about keeping your Hibernate session open over long periods of application existence (such as while you're waiting for user input). A single session is used for a specific and bounded operation in the application, something like populating the user interface or making a change that has been committed by the user. The next operation will use a new session. Also note that Session objects are not thread safe, so they cannot be shared between threads. Each thread needs to obtain its own session from the factory.

现在开始讲述“持久化操作”。在第27行,使用SessionFactory打开了Session,建立了数据库JDBC的连接,(该连接已经进行了初始化),我们可以借用它进行一系列的操作,例如:创建、获取、操纵、删除持久化对象。只要session处于open状态,那么对数据库的连接就一直建立着,所有对已经和session绑定的持久化对象的操作都会被记录下来,并且在session关闭的时候,所有的这些操作就会被更新到数据库中。从概念上理解,你可以将session看作一个在持久化对象和数据库之间的“大规模的事务”,它可以跨越几个数据库事务。正如数据库事务那样,你不该在程序中将hibernate session长时间的打开着(例如当程序在等待用户输入的时候),程序中的每个单独的操作都该采用单独的session,例如在“弹出用户界面,或者将用户的修改提交到数据库”中,就该使用两个session。同样需要注意的是,session是线程不安全的,因此无法在线程之间共享session,每个线程都应该使用SessionFactory建立自己的sess。

We need to look more closely at the lifecycle of mapped objects in Hibernate, and how this relates to sessions, because the terminology is rather specific and the concepts are quite important. A mapped object such as an instance of our Track class moves back and forth between two states with respect to Hibernate: transient and persistent. An object that is transient is not associated with any session. When you first create a Track instance using new(), it is transient; unless you tell Hibernate to persist it, the object will vanish when it is garbage collected or your application terminates.

下面我们对hibernate中被映射对象的声明周期进行说明,因为被映射对象相关的术语是相当特别的、它的概念也是很重要的。在hibernate中,被映射对象(例如程序中的Track对象)会在两个状态中不断的来回切换:临时(transient)状态和持久(persistent)状态。未曾与session绑定的对象就处于临时状态,例如程序中刚开始new出来的Track对象,它就处于临时状态。除非你通知hibernate对它进行持久化,否则整个对象就会在垃圾收集器回收或者程序结束的时候消逝。

Passing a transient mapped object to a Session's save() method causes it to become persistent. It will survive garbage collection and termination of the Java VM, staying available until it is explicitly deleted. (There is a related distinction between entities and values discussed at the beginning of Appendix A. Mapped objects that have been persisted are called entities, even if they do not currently exist as an instance in any virtual machine.) If you've got a persistent object and you call Session's delete() method on it, the object transitions back to a transient state. The object still exists as an instance in your application, but it is no longer going to stay around unless you change your mind and save it again; it's ceased being an entity.

但是,将一个临时对象使用session的save方法保存之后,它就处于持久状态,即使在垃圾回事或者Java VM结束之后,它都一直存在,知道该对象被明确删除为止(在附录A开头有相关“entities和values区别”的讨论,即使其在虚拟机中并不真实存在着一个对象与之相对应)。当你对持久化对象调用session.delete()方法时,该对象又变为临时状态。虽然该对象仍然在程序中做为一个实例存在着,但是除非你改变主意再次将其持久化,那么它将很快的消逝,它的“实体(entity)”也就愕然而之。

On the other hand, and this point is worth extra emphasis, if you haven't deleted an object (so it's still persistent), when you change its properties there is no need to save it again for those changes to be reflected in the database. Hibernate automatically tracks changes to any persistent objects and flushes those changes to the database at appropriate times. When you close the session, any pending changes are flushed.

另一方面,需要强调的是:如若你不删除某持久化对象,那么当你改变其属性时,并不需要显示的对其的改变进行保存。hibernate将会自动的跟踪到你对持久化对象的改变,然后在适当的时候将这些改变填入到数据库中。

An important but subtle point concerns the status of persistent objects you worked with in a session that has been closed, such as after you run a query to find all entities matching some criteria (you'll see how to do this in the upcoming section, 'Finding Persistent Objects'). As noted above, you don't want to keep this session around longer than necessary to perform the database operation, so you close it once your queries are finished. What's the deal with the mapped objects you've loaded at this point? Well, they were persistent while the session was around, but once they are no longer associated with an active session (in this case because the session has been closed) they are not persistent any longer. Now, this doesn't mean that they no longer exist in the database; indeed, if you run the query again (assuming nobody has changed the data in the meantime), you'll get back the same set of objects; they're still entities. It simply means that there is not currently an active correspondence being maintained between the state of the objects in your virtual machine and the database. It is perfectly reasonable to carry on working with the objects. If you later need to make changes to the objects and you want the changes to 'stick,' you will open a new session and use it to save the changed objects. Because each entity has a unique ID, Hibernate has no problem figuring out how to link the transient objects back to the appropriate persistent state in the new session.

下面讨论“在session关闭后,和session绑定的持久化对象的状态”的问题。例如当你执行了一个查询,得到了你所需要的实体对象之后,正如前面所述的那样,你不应该将session保持过久,使之超出数据库操作的范围,这时候你将会关闭session。那么此时那些已经载入的映射对象处于什么状态呢?答案是这样的,在session的打开的过程中,它是处于持久化状态,但是它一旦不在和active session(因为此时session已经关闭)绑定,那么它就处于持久化状态。但是,这并不意味着他们在数据库中就不再存在,事实上,如果你再次执行查询(假设此间无人修改数据),那么你将可以得到同样的集合数据。也就是说,虚拟机中的对象所处的状态和数据库中的实体数据的状态之间并没有必然的联系。这时候,你可以对那些对象进行自己的操作,如果你改变了一些对象的数据,并想将其存储到数据库中,那么你必须重新建立一个session,使用它保存那些经过改变的数据。因为每个实体都有自己的唯一ID,因此hibernate可以很容易的在新的session中计算出如何将临时对象重新转换为相应的持久对象。

Armed with these concepts and terms, the remainder of the example is easy enough to understand. Line 31 sets up a database transaction using our open session. Within that, we create a few Track instances containing sample data and save them in the session (lines 33-50), turning them from transient instances into persistent entities. Finally, line 53 commits our transaction, atomically (as a single, indivisible unit) making all the database changes permanent. The try/catch/finally block wrapped around all this shows an important and useful idiom for working with transactions. If anything goes wrong, lines 56-60 will roll back the transaction and then bubble out the exception, leaving the database the way we found it. The session is closed in the finally portion at line 63, ensuring that this takes place whether we exit through the 'happy path' of a successful commit, or via an exception that caused rollback. Either way, it gets closed as it should.

通过上面的概念的讲述和讨论,那么例子中的其他部分也就很好理解了。第31行,使用打开的session建立了数据库事务。在事务中,33-50行创建了一个Track对象,并在session中将其保存,将其从临时对象变为持久对象。最后,53行提交事务,原子性的执行数据库改变。这里的try/catch/finally封装了事务处理中常出现的idom。一旦出现任何问题,56-60行就会回滚事务,然后抛出异常,保证数据库维持原状。无论如何,都会执行finnally块中的63行,无论在成功执行或者出现错误回滚的情况下,都会关闭session。

At the end of our method we also close the session factory itself on line 67. This is something you'd do in the 'graceful shutdown' section of your application. In a web application environment, it would be in the appropriate lifecycle event handler. [3.1] In this simple example, when the main() method returns, the application is ending.

在方法的最后67行,将会关闭session factory。这是你的应用程序正常退出时应该执行的操作。在Web程序中,你则需要使用一定的生命周期事件处理器,完成此操作。在我们的例子中,在main退出的时候,也就是程序中止的时间。
 

posted on 2005-04-01 14:21 jinfeng_wang 阅读(1178) 评论(0)  编辑  收藏 所属分类: hibernate

只有注册用户登录后才能发表评论。


网站导航: