JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java Application Framework » Spring  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
作者 關於Spring+Hibernate取資料碰到的問題
我是捷克

我承認我有做糟糕本翻譯...



發文: 314
積分: 0
於 2009-07-14 22:25 user profilesend a private message to usersend email to 我是捷克reply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
各位前輩大家好, 小弟最近開始接觸及使用Spring+Hibernate等的FrameWork,
現在還在摸索階段.

我嚐試將Hibernate和我的Tomcat Service接起來的時候碰到了一些問題.

=========================
我目前的環境如下:
JDK 1.6.0_13
Tomcat 6.0

Hibernate 3 //為了不想寫SQL所以使用
MySQL DB Server 5.1 //因為不想花錢所以使用

Hessian-3.2.0 //用來將Java RMI轉為可被Flex接受的API
Flex 3 //前端畫面, 用來完全取代JSP

SpringFramework 3
=========================

我參考了"良"的Spring 2技術手冊後...

建立了一個J2EE的專案, 並在預設的WebContent下面的web.xml設定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>Auto-Profiling</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>
      org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/service-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>*.service</url-pattern>
  </servlet-mapping>
</web-app>


contextConfigLocation有指定讀取service-config.xml的設定, 設定如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 
<beans>
  <!-- 所有提供的API以及其映射 -->
    <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
        <property name="mappings"> 
            <props>
                <prop key="/account.service">accountServiceExporter</prop> 
            </props>
        </property>
    </bean>
    
    <!-- 資料庫相關設定 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> 
        <property name="url" value="jdbc:mysql://localhost:3333/auto-profiling"></property> 
        <property name="username" value="root"></property> 
        <property name="password" value="@monkey#"></property>  
    </bean>
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" destroy-method="destroy"> 
        <property name="dataSource" ref="dataSource"></property> 
        <property name="mappingResources"> 
            <list>
              <value>controller/User.hbm.xml</value>
            </list> 
        </property> 
        <property name="hibernateProperties"> 
            <props> 
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>               
                <prop key="hibernate.cache.use_query_cache">true</prop>
                <prop key="hibernate.jdbc.fetch_size">10</prop> 
            </props>
        </property>
    </bean>
    
    <!-- 使用者帳號相關API -->
    <bean id="accountService" class="dao.UserDAO"/>
    <bean id="accountServiceExporter" class="org.springframework.remoting.caucho.HessianServiceExporter">
        <property name="service" ref="accountService"></property>
        <property name="serviceInterface" value="dao.IUserDAO"></property>
    </bean>
</beans>


IUserDAO.java如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package dao;
 
import java.util.List;
 
import controlData.User;
 
public interface IUserDAO
{
  public String doSomeService(String some);
  
  public void insert(User user);
  
  public void delete(User user);
  
  public void update(User user);
  
  public User findById(Integer id);
  
  public List<User>findByName(String name);
  
  public List<User>findByOwner(String owner);
}


UserDAO.java如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package dao;
 
import java.util.List;
 
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
 
import controlData.User;
import exception.NoSuchOwnerException;
 
public class UserDAO implements IUserDAO
{
  private SessionFactory sessionFactory;
  
  public UserDAO() {}
  public UserDAO(SessionFactory sessionFactory)
  {
    this.setSessionFactory(sessionFactory);
  }
  
  public void setSessionFactory(SessionFactory sessionFactory)
  {
    this.sessionFactory = sessionFactory;
  }
  
  public String doSomeService(String some)
  {
    Session session = sessionFactory.openSession();
    try
    {
      Criteria cur_criteria = session.createCriteria(User.class);
      cur_criteria.add(Restrictions.eq("name", some));
      cur_criteria.setMaxResults(1);
      List<User>result = cur_criteria.list();
      if(result.size()>0)
      {
        return result.get(0).getName();
      }
    }
    catch(Exception ex)
    {
      ex.printStackTrace();
    }
    return null;
  }
  
  public User findById(Integer id)
  {
    Session session = sessionFactory.openSession();
    User user = (User) session.get(User.class, id);
    Hibernate.initialize(user);
    session.close();
    return user;
  }
  
  @SuppressWarnings("unchecked")
  public List<User>findByName(String search_name)
  {
    Session session = sessionFactory.openSession();
    
    Criteria cur_criteria = session.createCriteria(User.class);
    cur_criteria.add(Restrictions.eq("name", search_name));
    cur_criteria.setMaxResults(1);
    
    List<User>result = cur_criteria.list();
    return result;
  }
  
  @SuppressWarnings("unchecked")
  public List<User> findByOwner(String search_owner)
  {
    Session session = sessionFactory.openSession();
    
    Criteria cur_criteria = session.createCriteria(User.class);
    cur_criteria.add(Restrictions.eq("owner", search_owner));
    
    List<User>result = cur_criteria.list();
    return result;
  }
  
  public void insert(User insert_user)
  {
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    try
    {
      if(insert_user.getOwner() != null)
      {
        Integer owner_id = insert_user.getOwner();
        if(session.get(User.class, owner_id) == null) throw new NoSuchOwnerException();
      }
      session.save(insert_user);
      tx.commit();
    }
    catch(Exception ex)
    {
      ex.printStackTrace();
      if (tx!=null)
      {
        tx.rollback();
      }
    }
    finally
    {
      session.close();
    }
  }
  
  public void delete(User del_user)
  {
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    try
    {
      //若欲刪除的使用者是最上曾使用者的話則必須連帶將所屬人員刪除[START]
      if(del_user.getOwner() == null)
      {
        Criteria cur_criteria = session.createCriteria(User.class);
        cur_criteria.add(Restrictions.eq("owner", del_user.getOwner()));
        List<User>sub_users = cur_criteria.list();
        for(int i=0;i<sub_users.size();i++)
        {
          User cur_user = sub_users.get(i);
          session.delete(cur_user);
        }
      }
      //若欲刪除的使用者是最上曾使用者的話則必須連帶將所屬人員刪除[END]
      
      session.delete(del_user);
      tx.commit();
    }
    catch(Exception ex)
    {
      if (tx!=null)
      {
        tx.rollback();
      }
    }
    finally
    {
      session.close();
    }
  }
  
  public void update(User update_user)
  {
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    try
    {
      if(update_user.getOwner() != null)
      {
        Integer owner_id = update_user.getOwner();
        if(session.get(User.class, owner_id) == null) throw new NoSuchOwnerException();
      }
      
      session.update(update_user);
      tx.commit();
    }
    catch(Exception ex)
    {
      if (tx!=null)
      {
        tx.rollback();
      }
    }
    finally
    {
      session.close();
    }
  }
}


User.hbm.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="controlData.User" table="user"> 
        <id name="id" column="id" type="java.lang.Integer">
          <generator class="identity"/>
        </id>
        <property name="name" column="name" length="20" type="java.lang.String" not-null="true"/>
        <property name="password" column="password" length="20" type="java.lang.String" not-null="true"/>
        <property name="age" column="age" type="java.lang.Integer" not-null="true"/>
        <property name="sex" column="sex" type="java.lang.Integer" not-null="true"/>
        <property name="owner" column="owner" type="java.lang.Integer" not-null="false"/>
        <property name="current_level" column="current_level" type="java.lang.Integer" not-null="false"/>
        <filter name="nameFilter" condition="name in (:names)" />
    </class>
</hibernate-mapping>


User.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package controlData;
 
public class User
{
  private Integer  id;
  private String  name;
  private String  password;
  private Integer  age;
  private Integer  sex;
  private Integer  owner;
  private Integer  current_level;
  
  public Integer getId()
  {
    return id;
  }
  public void setId(Integer id)
  {
    this.id = id;
  }
  public String getName()
  {
    return name;
  }
  public void setName(String name)
  {
    this.name = name;
  }
  public String getPassword()
  {
    return password;
  }
  public void setPassword(String password)
  {
    this.password = password;
  }
  public Integer getAge()
  {
    return age;
  }
  public void setAge(Integer age)
  {
    this.age = age;
  }
  public Integer getSex()
  {
    return sex;
  }
  public void setSex(Integer sex)
  {
    this.sex = sex;
  }
  public Integer getOwner()
  {
    return owner;
  }
  public void setOwner(Integer owner)
  {
    this.owner = owner;
  }
  public Integer getCurrent_level()
  {
    return current_level;
  }
  public void setCurrent_level(Integer current_level)
  {
    this.current_level = current_level;
  }
  
}


我再服務起來的時候沒有任何問題, 問題是在Flex產生的swf再呼叫API的時候就會讓Engine
拋出Exception.

我的Flex程式如下index.mxml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:word = "*" implements="mx.rpc.IResponder" layout="absolute" width="100%" height="100%">
  <mx:Script>
    <![CDATA[
      import hessian.client.HessianService;
      import mx.rpc.AsyncToken;
      import mx.rpc.events.ResultEvent;
      import mx.controls.Alert;
      private var service:HessianService = new HessianService("account.service");
      private function getAccount():void
      {
        var token:AsyncToken = service.doSomeService.send("jacques");
        token.addResponder(this);
      }
      public function result(data:Object):void
      {
        var event:ResultEvent=data as ResultEvent;
        result_label.text = event.result as String;
      }
      public function fault(info:Object):void
      {
      }
    ]]>
  </mx:Script>
  <mx:TextInput id="input_box" text="" height="24" left="10" right="10" top="10"/>
  <mx:Button label="Button" click="getAccount()"  right="10" top="42"/>
  <mx:Label id="result_label" text="" right="10" left="10" top="72" bottom="10"/>
</mx:Application>


而錯誤訊息如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2009/7/15 上午 12:55:47 org.apache.catalina.core.StandardWrapperValve invoke
嚴重的: Servlet.service() for servlet dispatcherServlet threw exception
com.caucho.hessian.io.HessianProtocolException: expected hessian call ('c') at 0x43 (C)
  at com.caucho.hessian.io.Hessian2Input.error(Hessian2Input.java:2705)
  at com.caucho.hessian.io.Hessian2Input.readCall(Hessian2Input.java:203)
  at org.springframework.remoting.caucho.HessianExporter.doInvoke(HessianExporter.java:151)
  at org.springframework.remoting.caucho.HessianExporter.invoke(HessianExporter.java:119)
  at org.springframework.remoting.caucho.HessianServiceExporter.handleRequest(HessianServiceExporter.java:66)
  at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:49)
  at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:763)
  at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:709)
  at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:613)
  at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:536)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
  at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
  at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
  at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
  at java.lang.Thread.run(Unknown Source)


請教有經驗的前輩可否給予指導...

感謝


我是捷克 edited on 2009-07-15 00:56
reply to postreply to post
作者 Re:關於Spring+Hibernate取資料碰到的問題 [Re:我是捷克]
awei070571





發文: 90
積分: 0
於 2009-07-15 12:02 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
看起來像是 xml 的編碼與檔案儲存時的編碼不一樣

reply to postreply to post
作者 Re:關於Spring+Hibernate取資料碰到的問題 [Re:awei070571]
我是捷克

我承認我有做糟糕本翻譯...



發文: 314
積分: 0
於 2009-07-15 15:15 user profilesend a private message to usersend email to 我是捷克reply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
我傳遞API資訊的部分我是用Hessian做的, 記得Hessian傳的是bytes不是XML文字,
bytes的資訊的生成和接收都是Hessian在掌握的, 如果是這樣的話是表示說我採到
Hessian家的Bug了嗎...

我有嚐試換用其他版本的Hessian(都是3+版本, 因為Spring3的關係不能用3-的版本)
但都發生一樣的問題...

其實稍早我有更簡單的版本, 也是Spring+Hessian推資料再由Flex來拉資料, 那時候
是可以拿的到的, 但現在卻發生這樣的狀況...


reply to postreply to post
作者 Re:關於Spring+Hibernate取資料碰到的問題 [Re:我是捷克]
maisky





發文: 85
積分: 0
於 2009-07-16 02:39 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
首先呢, 在 service-config.xml 裡, accountService 這個 bean (也就是 UserDAO) 還需要注入一個 sessionFactory.

<bean id="accountService" class="dao.UserDAO"/> // 光是這樣是不夠的

再來, 根據一些看到的討論, hessian 和 Spring 3.0 之間還是有點問題, hessian-flex 本真也有問題.
你大概也是踩到地雷了.

http://furiouspurpose.blogspot.com/2009/06/dependency-trap-hessian-spring-tapestry.html
http://jira.springframework.org/browse/SPR-5469
http://www.mail-archive.com/hessian-interest@caucho.com/msg00726.html

我有照著你給的東西試了一下, 看起來都正常, 沒有和你一樣的錯誤訊息

MySQL 5.1
Tomcat 6.0
Spring 3.0.0.M3
Hibernate 3.2.1.ga
Hessian 3.2.1
Hessian-flex 4.0.0
Flex builder 3

你要不要試著用新版的 hessian 和 hessian-flex 試試看啊


reply to postreply to post
作者 Re:關於Spring+Hibernate取資料碰到的問題 [Re:maisky]
我是捷克

我承認我有做糟糕本翻譯...



發文: 314
積分: 0
於 2009-07-16 04:10 user profilesend a private message to usersend email to 我是捷克reply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
在修改maisky所指出的錯誤並更換jar為hessian 3.2.1後就可以動了...\(^o^)/
才剛學就採到地雷真是前途無亮啊...

接下來要做的就是利用doSomeService以外的方法拿到並使用回傳的客制
物件(User等)...

總之, 感謝maisky還有大家的幫忙...(未完續待Big Smile)


reply to postreply to post
作者 Re:關於Spring+Hibernate取資料碰到的問題 [Re:我是捷克]
我是捷克

我承認我有做糟糕本翻譯...



發文: 314
積分: 0
於 2009-07-16 21:42 user profilesend a private message to usersend email to 我是捷克reply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
持續修改程式後遇上了一個使用者登陸Session的問題,
這次的問題算是比較偏向設計的問題,

問題是這樣的, 我除了原先的User資料表外又建立一個
UserSession的資料表, 這資料表主要就是紀錄使用者登
陸狀況的資料表...

我在Flex的前端程式這邊新建立一個LoginWindow的元
件用來登陸應用程式, 但問題就出在這裡...

LoginWindow中包含帳號密碼的輸入欄位(String)及一個
登陸按鈕, 按下按鈕後會呼叫Hessian API拿到IUserDAO
並呼叫裡面的userLogin方法...

userLogin方法除了會驗證User的資料表的該帳號密碼正
不正確外, 還會在確認正確的時候跑去UserSession資料
表中更新該使用者的登陸狀況並將UserSession物件傳回...

寫到這裡的時候就感覺不對勁, 到底在UserDAO的方法中
設計會傳回UserSession物件的登陸方法到底正不正確呢?

還是我應該採用Flex SSO(如果有的話)的機制呢?

感謝任何回應和指教


我是捷克 edited on 2009-07-16 21:45
reply to postreply to post
» JWorld@TW »  Java Application Framework » Spring

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8