<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    網(wǎng)路冷眼@BlogJava

    熙熙攘攘一閑人 以冷靜的眼光觀察技術(shù)
    posts - 88, comments - 193, trackbacks - 0, articles - 28
      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
    原文地址:http://wiki.netbeans.org/wiki/view/UsingHibernateWithJPA

    Using Hibernate-specific features with JPA

    The Java Persistence API offers a powerful standard for persisting POJOs.It includes all the most important features which you would expect from an object-relational mapping tool, but there are still some areas where you might need to use vendor-specific features. In this tutorial, we will show how to use Hibernate-specific features for validating and querying while using the standard API for the rest.

    Prerequisites

    This tutorial assumes you have some basic knowledge of, or programming experience with, the following technologies:

    • Java Server Faces
    • Java Persistence API.
    • NetBeans IDE

    This tutorial is partly based on the Using Hibernate With Java Persistence API tutorial, you might want to go through it first.

    Software Needed for the Tutorial

    Before you begin, you need to install the following software on your computer:

    • NetBeans IDE 5.5.1 (download)
    • Sun Java System Application Server, Platform Edition 9 (download)
    • Hibernate Core 3.2.1.GA, Hibernate EntityManager 3.2.1.GA(download)

    Setting up your Environment

    First we will create a library in the IDE for the Hibernate entity manager.

    1. Unzip the Hibernate JAR files to any temporary location
    2. Choose Tools > Library Manager from the main menu. Click New Library, name the library Hibernate, and click OK.
    3. In the Libraries pane of the Library Manager dialog box, select the Hibernate library you just created.
    4. Click the Classpath tab and then click Add JAR/Folder and locate the following JAR files:
    • From Hibernate EntityManager:
      • hibernate-entitymanager.jar
      • lib/hibernate-annotations.jar
      • lib/jboss-archive-browsing.jar
      • lib/javassist.jar
    • From Hibernate Core:
      • hibernate3.jar
      • lib/antlr-2.7.6.jar
      • lib/asm-attrs.jar
      • lib/asm.jar
      • lib/c3p0-0.9.0.jar
      • lib/cglib-2.1.3.jar
      • lib/commons-collections-2.1.1.jar
      • lib/concurrent-1.3.2.jar
      • lib/commons-logging-1.0.4.jar
      • lib/dom4j-1.6.1.jar
      • lib/ehcache-1.2.3.jar
      • lib/log4j-1.2.11.jar

    Creating a Web Application

    Next we will create a web application with entity classes and a JSF interface. To speed up the process, we will use the CRUD generators in the IDE.
    • Choose File > New Project (Ctrl-Shift-N). Select Web Application from the Web category.
    • Name the project HibernateWithJPA, set the server to Sun Java System Application Server, the Java EE version to Java EE 5 and make sure that the Set Source Level to 1.5 checkbox is checked. Click Next.
    • Select the JavaServer Faces framework and click Finish.
    • Add the Hibernate library we created earliead to the project by right-clicking the project node and choosing Properties > Libraries > Add Library > Hibernate
    • In the Projects window, right-click the project node and choose New > Entity Classes from Database.
    • In the Data Source drop-down, select the jdbc/sample database. If prompted for a user name and password, use app and app. Select the CUSTOMER table from the list, click Add and then click Next. * Leave the tables and class names as their default, and set the package to sample.entities.
    • Now it is time to create the persistence unit. Click the Create Persistence Unit button. Accept the default name, select Hibernate as the persistence provider, and select None as the table generation strategy. Click OK.
    • Click Finish in the Entity Classes from Database wizard. The IDE creates the persistence unit (persistence.xml under Configuration Files node) and the entity classes (under Source Packages).
    • Set a correct SQL dialect for Hibernate. Double-click persistence.xml and click the XML button at the top of the editor to switch to the XML view. Add the following property to the persistence unit:
            <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" />
    

    Coding the JSF Interface

    Now we can quickly generate JSF pages for the entity classes with the NetBeans IDE CRUD generation.

    1. Right-click the project node and choose New > JSF Pages from Entity Class. Add both Customer.java and DiscountCode.java to the list of selected classes and click Next.
    2. Change the package to sample.controller and click Finish.
    JSF from entities

    Testing the Project

    At this point we will try to run the application and see whether everything is working as expected.

    1. Right-click the project and choose Run Project. The IDE starts the application server, builds and deploys the application, and shows index.jsp in the external web browser.
    2. Click the List of Customer link and you should see the following web page:
    list of customers
    • Use the New Customer link to create a customer

    Adding validation

    When creating a new customer you might have noticed that values were not validated before attempting to persist the newly created customer. We could use the validation facilities in JSF for ensuring that only correct values are inserted, but since this tutorial is about Hibernate we will instead demonstrate how to use the Hibernate validation framework. This approach has an additional advantage that the validation rules need to be specified only once even if another type of client is added.

    Open Customer.java in the editor and add the following annotations on its member variables:

        @Column(name = "STATE")
    @Length(min=2, max=2, message="not a valid state")
    private String state;
    @Column(name = "EMAIL")
    @Email
    private String email;
    
    For simplicity's sake we will only add validation to state and email properties. The @Length annotation validates that the length of the property will be within the range specified by min and max attributes. We apply it on the state property to make sure that it is exactly 2 characters long. We also specify a value for the message attribute, it will be the shown error message when the validation fails. The @Email annotation in turn validates that the property represents a valid email address, as you might have guessed.

    Now that we have our domain object annotated, we need to add handling of validation errors to our controller class. So open CustomerController.java and add the following method there:

        /**
    * Validates the given customer.
    * @return true if there were no validation errors, false otherwise.
    */
    private boolean validate(Customer customer){
    ClassValidator customerValidator = new ClassValidator(Customer.class);
    // get the invalid values
    InvalidValue[] msgs = customerValidator.getInvalidValues(customer);
    if (msgs.length > 0){
    for(InvalidValue msg : msgs){
    // add an error message for each invalid value, these
    // messages will be shown to the user
    addErrorMessage(msg.getMessage());
    }
    return false;
    }
    return true;
    }
    
    This method will first create a class validator for our Customer class and then process the validation rules we specified earlier when. We collect the invalid value messages and add each of them as error messages to the FacesContext (this is done by the addErrorMessage method). If there were no validation errors the will return true, false otherwise. Of course, as such this method is not very useful unless we invoke it in the right places. We probably want to validate the values both when a new customer is created and when an existing customer is edited. So let's first modify the create method to check whether there were any validation errors before attempting to persist:
        public String create() {
    if (!validate(customer)){
    // return to the input page if there were any validation errors
    return null;
    }
    EntityManager em = getEntityManager();
    try {
    utx.begin();
    em.joinTransaction();
    em.persist(customer);
    ...
    

    As you can see, we return null if any errors were found - this means JSF will display the same page again. Make a similar modification to the edit method as well and run the application. Try to create a new customer with an invalid email address and with a 3 characters long state code. This is what you should see: not a valid customer

    Query by Example

    While the Java Persistence QL is an impressive query language, there are cases when a different kind of API is more suitable. Luckily, in addition to JPQL support, Hibernate features a criteria query API which you can leverage for the cases it is needed and stick to the standard API elsewhere in the application. In the following example we will demonstrate the Query By Example approach using Hibernate's Criteria API.

    First we need to create a new page for our new query functionality. Create a new page named Query.jsp in the customer folder and paste the following to it:

    <%@page contentType="text/html"%>
    <%@page pageEncoding="UTF-8"%>
    <%@taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
    <%@taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Query By Example</title>
    </head>
    <body>
    <f:view>
    <h1>Query By Example</h1>
    <h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>
    <h:form>
    <h:panelGrid columns="2">
    <h:outputText value="Zip:"/>
    <h:inputText id="zip" value="#{customer.customer.zip}" converter="stringConverter" title="Zip" />
    <h:outputText value="Name:"/>
    <h:inputText id="name" value="#{customer.customer.name}" converter="stringConverter" title="Name" />
    <h:outputText value="State:"/>
    <h:inputText id="state" value="#{customer.customer.state}" converter="stringConverter" title="State" />
    </h:panelGrid>
    <h:commandLink action="#{customer.queryByExample}" value="Search"/>
    </h:form>
    <h:form>
    <a href="/HibernateWithJPA/index.jsp">Back to index</a>
    <br>
    <h:dataTable value='#{customer.model}' var='item' border="1" cellpadding="2" cellspacing="0">
    <h:column>
    <f:facet name="header">
    <h:outputText value="CustomerId"/>
    </f:facet>
    <h:commandLink action="#{customer.detailSetup}" value="#{item.customerId}"/>
    </h:column>
    <h:column>
    <f:facet name="header">
    <h:outputText value="Zip"/>
    </f:facet>
    <h:outputText value="#{item.zip}"/>
    </h:column>
    <h:column>
    <f:facet name="header">
    <h:outputText value="Name"/>
    </f:facet>
    <h:outputText value="#{item.name}"/>
    </h:column>
    <h:column>
    <f:facet name="header">
    <h:outputText value="Addressline1"/>
    </f:facet>
    <h:outputText value="#{item.addressline1}"/>
    </h:column>
    <h:column>
    <f:facet name="header">
    <h:outputText value="Addressline2"/>
    </f:facet>
    <h:outputText value="#{item.addressline2}"/>
    </h:column>
    <h:column>
    <f:facet name="header">
    <h:outputText value="City"/>
    </f:facet>
    <h:outputText value="#{item.city}"/>
    </h:column>
    <h:column>
    <f:facet name="header">
    <h:outputText value="State"/>
    </f:facet>
    <h:outputText value="#{item.state}"/>
    </h:column>
    <h:column>
    <f:facet name="header">
    <h:outputText value="Phone"/>
    </f:facet>
    <h:outputText value="#{item.phone}"/>
    </h:column>
    <h:column>
    <f:facet name="header">
    <h:outputText value="Fax"/>
    </f:facet>
    <h:outputText value="#{item.fax}"/>
    </h:column>
    <h:column>
    <f:facet name="header">
    <h:outputText value="Email"/>
    </f:facet>
    <h:outputText value="#{item.email}"/>
    </h:column>
    <h:column>
    <f:facet name="header">
    <h:outputText value="CreditLimit"/>
    </f:facet>
    <h:outputText value="#{item.creditLimit}"/>
    </h:column>
    <h:column>
    <f:facet name="header">
    <h:outputText value="DiscountCode"/>
    </f:facet>
    <h:outputText value="#{item.discountCode}"/>
    </h:column>
    <h:column>
    <h:commandLink value="Destroy" action="#{customer.destroy}">
    <f:param name="customerId" value="#{item.customerId}"/>
    </h:commandLink>
    <h:outputText value=" "/>
    <h:commandLink value="Edit" action="#{customer.editSetup}">
    <f:param name="customerId" value="#{item.customerId}"/>
    </h:commandLink>
    </h:column>
    </h:dataTable>
    </h:form>
    </f:view>
    </body>
    </html>
    
    There are a couple of things to note here. Firstly, we have specified "stringConverter" converter for the input fields. Secondly, the 'search' link will try to execute customer.queryByExample method, which we haven't yet implemented. Thirdly, the data table uses customer.model as its underlying model. We will get back to these in a minute, but before that we still need to create a link to our new page. To keep things simple, we will just add it to the customer/List.jsp page, right after the link to the New Customer page:
    <h:commandLink action="#{customer.createSetup}" value="New Customer"/>
    <br>
    <h:commandLink action="#{customer.querySetup}" value="Query Customers"/>
    

    Now, this link will cause querySetup method to be invoked in the CustomerController.java, so let's implement it next. To do that, add the following to the CustomerController.java:

       public String querySetup(){
    this.customer = new Customer();
    this.model = null;
    return "customer_query";
    }
    

    And to complete the UI side of things, we still need to add a navigation rule to faces-config.xml:

    <navigation-rule>
    <navigation-case>
    <from-outcome>customer_query</from-outcome>
    <to-view-id>/customer/Query.jsp</to-view-id>
    </navigation-case>
    </navigation-rule>
    

    What is still missing is the actual implementation of the query, and the converter we mentioned earlier. Let's tackle the implementation of the query method first. In the Query.jsp page we defined that the 'Search' link will invoke customer.queryByExample method and that customer.model will be used for the data table. To satisfy the latter, we just need to create a getter for the model in CustomerController.java - press ctrl-space and choose 'create getter getModel for field model'. After that, add the following method:

        /**
    * Queries customers based on the values in our <code>customer</code>.
    */
    public String queryByExample(){
    // get the native hibernate session
    Session session = (Session) getEntityManager().getDelegate();
    // create an example from our customer, exclude all zero valued numeric properties
    Example customerExample = Example.create(customer).excludeZeroes();
    // create criteria based on the customer example
    Criteria criteria = session.createCriteria(Customer.class).add(customerExample);
    // perform the query and set the result to our model.
    this.model = new ListDataModel(criteria.list());
    return "customer_query";
    }
    

    You can see how easily you can access Hibernate's native API - just invoke getDelegate() on the entity manager and cast it to org.hibernate.Session. Once we have the access to Session we can take advantage of the Criteria API. In the above method we create an example criteria based on the customer and execute the query. If you are not familiar with the Criteria API, it is probably worth explaining a bit. By default, all null values will be excluded, which means that the properties on our customer that were null, will not be part of the criteria. In addition, we specify that all zero valued numeric properties will be excluded as well. Here it gets a bit complicated: since JSF by default converts strings without values to empty strings (instead of nulls), we need to create a special converter for dealing with the conversion of strings from the query page. The implementation of the converter is as simple as:

    package sample.controller;
    import javax.faces.component.UIComponent;
    import javax.faces.context.FacesContext;
    import javax.faces.convert.Converter;
    /**
    * A converter for string values that does not
    * convert <code>null</code> values to empty strings.
    */
    public class StringConverter implements Converter{
    /** Creates a new instance of StringConverter */
    public StringConverter() {
    }
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
    if(value == null || "".equals(value)){
    return null;
    }
    return value;
    }
    public String getAsString(FacesContext context, UIComponent component, Object value) {
    return value != null ? value.toString() : null;
    }
    }
    

    Don't forget to register the converter in faces-config.xml:

    <converter>
    <converter-id>stringConverter</converter-id>>
    <converter-class>sample.controller.StringConverter</converter-class>
    </converter>
    

    Finally, we are ready to run the application once again and test the new functionality:

    query by exmpale

    Troubleshooting

    In case you are using NetBeans 5.5 instead of 5.5.1, you might run into issue 90031, which causes silent failures when inserting data. The workaround is to upgrade to 5.5.1 or to manually add em.joinTransaction() after each call to utx.begin() in the generated controller classes.

    Download the source code for this tutorial here(info)

    Attachments

    主站蜘蛛池模板: 很黄很黄的网站免费的| 亚洲精品在线视频观看| 国产亚洲成av人片在线观看| 久久亚洲精品国产精品黑人| 亚洲欧洲一区二区三区| 成人永久免费高清| 久久久久久A亚洲欧洲AV冫| 亚洲av综合色区| 亚洲一区二区三区四区视频| 亚洲AV无码AV日韩AV网站| 国产精品无码永久免费888| 99re6免费视频| 日本一道一区二区免费看 | 亚洲精品无码久久毛片| 亚洲AV中文无码字幕色三| 亚洲一区二区影视| 乱人伦中文视频在线观看免费| 性无码免费一区二区三区在线| 国产精品久久久久久久久久免费| 亚洲av无码国产精品色在线看不卡 | 国产亚洲精品国产| 亚洲国产精品无码久久久| 日本高清免费中文在线看| 97在线视频免费| 亚洲AV无码一区二区三区在线观看| 亚洲av中文无码乱人伦在线播放| 亚洲精品一二三区| 中文字幕不卡免费高清视频| 无码日韩人妻av一区免费| 亚洲中文久久精品无码| 亚洲天堂2016| 中文字幕乱码亚洲无线三区| 国产男女爽爽爽免费视频| 你懂的在线免费观看| 成人免费看吃奶视频网站| 亚洲国产精品国自产拍AV| 亚洲AV女人18毛片水真多| 久久综合给合久久国产免费| 亚洲国产精品人人做人人爽| 亚洲成人黄色在线| 两个人看的www视频免费完整版|