lyyb2001

          只是為方便自己找記錄而已
          posts - 57, comments - 27, trackbacks - 0, articles - 5
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 ::  :: 管理

          Hibernate的單向Many-to-one關系問題解決

          Posted on 2008-12-10 15:41 skycity 閱讀(5212) 評論(0)  編輯  收藏 所屬分類: Hibernate相關Spring框架

          我在使用雙向Many-to-one關系時,想實現數據字典管理,1的一端是數據字典類別比如"性別","學歷",many一端通過外鍵進行引用.
          1.單獨對1的一端進行crud都沒有問題,建好連接以后,刪除1端,many同時刪除有聯系的記錄
          2.設置好了表間的聯系.進行CRD沒啥問題.update的時候,不對外鍵進行任何修改時.正常運行.修改外鍵時,報如下錯誤
          ?javax.servlet.ServletException: org.springframework.orm.hibernate3.HibernateSystemException: identifier of an instance of com.skycity.office.bean.DictType was altered from 4028898e1ae1d3d6011ae1d4dea70001 to 4028898e1abd9f87011abdc769de0003; nested exception is org.hibernate.HibernateException: identifier of an instance of com.skycity.office.bean.DictType was altered from 4028898e1ae1d3d6011ae1d4dea70001 to 4028898e1abd9f87011abdc769de0003
          網上找了很久.有的說不是many-to-many的問題.很多地方說什么merge().saveOrUpdate(),嘗試了很多,網上詳細的解決方案也沒有.將修改時調用的方法注釋了,還是會出現這種錯誤.有點崩潰的感覺
          試了merge().這里提到merge()也碰到一個奇怪的問題.merge按正常來說應該是合并的意思.我在many端修改時.使用了merge,居然one端進行了修改
          比如.我想將"性別"為"女"的類型改成"學歷"(當然這是我測試),他最后修改了我的字典類別表,將"性別"類別改成了"學歷"類別.不知道是什么原因.
          貼出我的部分代碼:
          字典類別表的POJO
          package com.skycity.office.bean;

          import java.util.HashSet;
          import java.util.Set;

          import javax.persistence.CascadeType;
          import javax.persistence.Entity;
          import javax.persistence.FetchType;
          import javax.persistence.OneToMany;
          import javax.persistence.Table;

          @Entity
          @Table(name = "PFDICTTYPE")
          public class DictType extends IdEntity{
          ?private String name;
          ?private String type;
          ?
          ?private Set<DictCode> dictCode=new HashSet<DictCode>();
          ?
          ?public String getName() {
          ??return name;
          ?}
          ?
          ?public void setName(String name) {
          ??this.name = name;
          ?}
          ?
          ?public String getType() {
          ??return type;
          ?}
          ?public void setType(String type) {
          ??this.type = type;
          ?}

          ?@OneToMany(mappedBy="dictType",cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
          ?public Set<DictCode> getDictCode() {
          ??return dictCode;
          ?}

          ?public void setDictCode(Set<DictCode> dictCode) {
          ??this.dictCode = dictCode;
          ?}
          }
          字典表的POJO
          package com.skycity.office.bean;


          import java.util.List;

          import javax.persistence.CascadeType;
          import javax.persistence.Entity;
          import javax.persistence.FetchType;
          import javax.persistence.JoinColumn;
          import javax.persistence.ManyToOne;
          import javax.persistence.Table;
          import javax.persistence.Transient;


          @Entity
          @Table(name = "PFDICTCODE")
          public class DictCode extends IdEntity{
          ??? private String dictName;
          ??? private String dictDesc;
          ??? private String dictValue;
          ???
          ??? private DictType dictType;

          ?@ManyToOne(cascade = { CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.LAZY)??
          ?@JoinColumn(name = "dictType",nullable = false,updatable=true,insertable = true)
          ??? public DictType getDictType() {
          ??? ?return dictType;
          ??? }
          ?public String getDictName() {
          ??return dictName;
          ?}
          ?public void setDictName(String dictName) {
          ??this.dictName = dictName;
          ?}
          ?public String getDictDesc() {
          ??return dictDesc;
          ?}
          ?public void setDictDesc(String dictDesc) {
          ??this.dictDesc = dictDesc;
          ?}
          ?public void setDictType(DictType dictType) {
          ??this.dictType = dictType;
          ?}
          ?
          ?public String getDictValue() {
          ??return dictValue;
          ?}
          ?
          ?public void setDictValue(String dictValue) {
          ??this.dictValue = dictValue;
          ?}
          ?
          ?@SuppressWarnings("unchecked")
          ?@Transient
          ?public List<String> getCheckedDictTypeIds() throws Exception {
          ??return null;// CollectionUtils.collectAsList(roles, "id");
          ?}
          }
          DictCode表的Service實現
          package com.skycity.office.service.impl;

          import java.sql.SQLException;
          import java.util.List;

          import org.hibernate.HibernateException;
          import org.hibernate.Session;
          import org.hibernate.SessionFactory;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.stereotype.Service;
          import org.springframework.transaction.annotation.Transactional;
          import org.springside.modules.orm.hibernate.Page;
          import org.springside.modules.orm.hibernate.SimpleHibernateTemplate;

          import com.skycity.office.bean.DictCode;
          import com.skycity.office.bean.DictType;

          @Service
          @Transactional(readOnly = true)
          public class DictCodeServiceImpl{

          ?private SimpleHibernateTemplate<DictCode, String> dictCodeDAO;
          ?private SimpleHibernateTemplate<DictType, String> dictTypeDAO;
          ?
          ?@Autowired
          ?public void setSessionFactory(SessionFactory sessionFactory) {
          ??dictCodeDAO = new SimpleHibernateTemplate<DictCode, String>(sessionFactory, DictCode.class);
          ??dictTypeDAO = new SimpleHibernateTemplate<DictType, String>(sessionFactory, DictType.class);
          ?}
          ?
          ?public Page<DictCode> getAllDictCodes(Page<DictCode> page) {
          ??return dictCodeDAO.findAll(page);
          ?}

          ?public DictCode getDictCode(String id) {
          ??return dictCodeDAO.get(id);
          ?}
          ?
          ?public List<DictType> getAllDictTypes() {
          ??return dictTypeDAO.findAll();
          ?}
          DictCode Action:
          package com.skycity.office.web.action;

          import java.util.List;

          import org.apache.struts2.config.ParentPackage;
          import org.apache.struts2.config.Result;
          import org.apache.struts2.config.Results;
          import org.apache.struts2.dispatcher.ServletActionRedirectResult;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springside.modules.orm.hibernate.Page;

          import com.skycity.office.bean.DictCode;
          import com.skycity.office.bean.DictType;
          import com.skycity.office.service.impl.DictCodeServiceImpl;
          import com.skycity.office.util.Constants;
          import com.skycity.office.web.struts2.CRUDActionSupport;

          @ParentPackage("default")
          @Results({
          @Result(name=CRUDActionSupport.SUCCESS, value="/list", type=ServletActionRedirectResult.class)
          })
          public class DictCodeAction extends CRUDActionSupport<DictCode>{
          ?private static final long serialVersionUID = 1L;
          ?@Autowired
          ?private DictCodeServiceImpl dictCodeService;
          ?private String id;
          ?private DictCode entity;
          ?private List<DictType> allDictTypes;
          ?
          ?private Page<DictCode> page = new Page<DictCode>(Constants.DEFAULT_PAGE_SIZE, true);

          ?@Override
          ?public String delete() throws Exception {
          ??dictCodeService.deleteDictCode(id);
          ??return RELOAD;
          ?}
          ?
          ?@Override
          ?public String edit() throws Exception {
          ??allDictTypes = dictCodeService.getAllDictTypes();
          ??return INPUT;
          ?}

          ?@Override
          ?public String list() throws Exception {
          ??page=dictCodeService.getAllDictCodes(page);
          ??return SUCCESS;
          ?}
          ?
          ?public String show() throws Exception{
          ??return SHOW;
          ?}

          ?@Override
          ?public String save() throws Exception {
          ??if (null!=id && !"".equals(id)){
          ???dictCodeService.updateDictCode(entity);
          ??}else{
          ???dictCodeService.saveDictCode(entity);
          ??}
          ??return RELOAD;
          ?}
          ?
          ?public void prepare() throws Exception {
          ??if (null!=id && !"".equals(id)) {
          ???entity = dictCodeService.getDictCode(id);
          ??} else {
          ???entity = new DictCode();
          ??}
          ?}

          ?public DictCode getModel() {
          ??return entity;
          ?}

          ?public Page<DictCode> getPage() {
          ??return page;
          ?}

          ?public String getId() {
          ??return id;
          ?}

          ?public void setId(String id) {
          ??this.id = id;
          ?}

          ?public DictCode getEntity() {
          ??return entity;
          ?}

          ?public void setEntity(DictCode entity) {
          ??this.entity = entity;
          ?}

          ?public List<DictType> getAllDictTypes() {
          ??return allDictTypes;
          ?}

          }

          ?
          ?@Transactional(readOnly=false)
          ?public void saveDictCode(DictCode authorities) {
          ??this.dictCodeDAO.save(authorities);
          ?}
          ?
          ?@Transactional(readOnly=false)
          ?public void updateDictCode(DictCode entity) throws HibernateException, SQLException {
          ??Session session=this.dictCodeDAO.getSession();
          ??session.clear();
          ??session.update(entity);
          ??
          ?}
          ?
          ?@Transactional(readOnly=false)
          ?public void deleteDictCode(String id) {
          ??this.dictCodeDAO.delete(id);
          ?}
          }
          因為我采用的sturts2.5+hibernate3.2所有的都支持JPA.所以都用的是JPA注釋,沒有其他servcie,action.dao,struts配置的xml文件.
          后來
          @Transactional(readOnly=false)
          ?public void updateDictCode(DictCode entity) throws HibernateException, SQLException {
          ??Session session=this.dictCodeDAO.getSession();
          ??session.clear();
          ??session.update(entity);
          ??
          ?}
          先對entity進行清空,然后在保存

          預計原因.當我想改變某一個字典信息時,講該字典信息和字典類別信息取出來,持久化了,想修改的時候無法修改.所以先clear()再存入.
          在update前clear()一下.成功解決該問題



          Lyyb2001
          主站蜘蛛池模板: 邯郸市| 沧州市| 汉源县| 兴山县| 铜陵市| 内黄县| 阿拉善右旗| 隆昌县| 沧源| 昌都县| 宜丰县| 门头沟区| 施甸县| 嘉兴市| 镇坪县| 东明县| 旅游| 五莲县| 亚东县| 沁源县| 襄城县| 宜良县| 印江| 金平| 大名县| 河北区| 襄汾县| 达拉特旗| 竹溪县| 建水县| 宁强县| 石泉县| 措勤县| 都江堰市| 华坪县| 自治县| 南雄市| 永定县| 冀州市| 荥经县| 苏尼特左旗|