hibernate中的对象的3种状态的理解及导致报错object references an unsaved transient instance - save the transient instance before flushing异常

  先看下这三篇博文:

object references an unsaved transient instance - save the transient instance before flushing异常问题处理

hibernate中持久化对象的生命周期(三态:自由态,持久态,游离态 之间的转换)

hibernate中对象的3种状态:瞬时态(Transient)、 持久态(Persistent)、脱管态(Detached)

  原来的导致报错的代码:

/**
* 详细信息UI
*/
public String showUI() {
if (!StringUtils.isBlank(deviceId)) {
device = deviceService.queryById(deviceId);
}
String deviceTypeName = null;
String deviceTypeNameString ="未知类型";
if(null!= device.getDeviceType()){
deviceTypeName = device.getDeviceType().getName();
deviceTypeNameString = MessageUtils.getMessage(deviceTypeName);
} DeviceType deviceType = new DeviceType();
deviceType.setName(deviceTypeNameString);
device.setDeviceType(deviceType);
if (device != null && device.getDeviceInfos().iterator().hasNext())
deviceInfo = device.getDeviceInfos().iterator().next();
String osNameString ="未知操作系统类型";
if(null != device.getOs()){
if(StringUtils.isNotBlank(device.getOs().getName())){
String osName = device.getOs().getName();
osNameString = MessageUtils.getMessage(osName);
}
}else{
device.setOs(new Os());
}
device.getOs().setName(osNameString);
String ufNameString ="未知设备用途";
if(null!=device.getDeviceUseful()){
if( StringUtils.isNotBlank(device.getDeviceUseful().getName())){
String ufName= device.getDeviceUseful().getName();
ufNameString = MessageUtils.getMessage(ufName);
}
}else{
device.setDeviceUseful(new DeviceUseful());
}
device.getDeviceUseful().setName(ufNameString);
//获取组织机构全路径
Organization organization=device.getOrganization();
if(organization!=null){
String Aname =organization.getName();
String name= getAname(organization, Aname);
device.getOrganization().setName(name);
} return RETURN_SHOWUI;
}

  错误点就在上面代码标红处,估计他这么写的意思就是像把国际化的名称转为汉语,但是这样写就会导致deviceType类中只有name是有值的,其他都是null,所以会报错:org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing:

  考虑可以修改成这样:

public String showUI() {
if (!StringUtils.isBlank(deviceId)) {
device = deviceService.queryById(deviceId);
}
String deviceTypeName = null;
String deviceTypeNameString ="未知类型";
if(null!= device.getDeviceType()){
deviceTypeName = device.getDeviceType().getName();
deviceTypeNameString = MessageUtils.getMessage(deviceTypeName);
device.getDeviceType().setName(deviceTypeNameString);
}else{
device.setDeviceType(new DeviceType());
} if (device != null && device.getDeviceInfos().iterator().hasNext())
deviceInfo = device.getDeviceInfos().iterator().next(); String osNameString ="未知操作系统类型";
if(null != device.getOs()){
if(StringUtils.isNotBlank(device.getOs().getName())){
String osName = device.getOs().getName();
osNameString = MessageUtils.getMessage(osName);
device.getOs().setName(osNameString);
}
}else{
device.setOs(new Os());
} String ufNameString ="未知设备用途";
if(null!=device.getDeviceUseful()){
if( StringUtils.isNotBlank(device.getDeviceUseful().getName())){
String ufName= device.getDeviceUseful().getName();
ufNameString = MessageUtils.getMessage(ufName);
device.getDeviceUseful().setName(ufNameString);
}
}else{
device.setDeviceUseful(new DeviceUseful());
} //获取组织机构全路径
Organization organization=device.getOrganization();
if(organization!=null){
String Aname =organization.getName();
String name= getAname(organization, Aname);
device.getOrganization().setName(name);
} return RETURN_SHOWUI;
}

  这样修改最重要的点就是上面标红处,但是依然有问题,就是当device.getDeviceUseful()等是null的时候,会报上面的异常,还是自由态的影响,所以考虑到放到session里面,到详情页面再直接取即可。

public String showUI() {
if (!StringUtils.isBlank(deviceId)) {
device = deviceService.queryById(deviceId);
}
String deviceTypeName ="未知类型";
if(null!= device.getDeviceType()){
deviceTypeName = MessageUtils.getMessage(device.getDeviceType().getName());
}
getRequest().setAttribute("deviceTypeName", deviceTypeName); if (device != null && device.getDeviceInfos().iterator().hasNext())
deviceInfo = device.getDeviceInfos().iterator().next(); String osName ="未知操作系统类型";
if(null != device.getOs()){
if(StringUtils.isNotBlank(device.getOs().getName())){
osName = MessageUtils.getMessage(device.getOs().getName());
}
}
getRequest().setAttribute("osName", osName); String ufName ="未知设备用途";
if(null!=device.getDeviceUseful()){
if(StringUtils.isNotBlank(device.getDeviceUseful().getName())){
ufName = MessageUtils.getMessage(device.getDeviceUseful().getName());
}
}
getRequest().setAttribute("ufName", ufName); //获取组织机构全路径
Organization organization=device.getOrganization();
if(organization!=null){
String Aname =organization.getName();
String name= getAname(organization, Aname);
device.getOrganization().setName(name);
} return RETURN_SHOWUI;
}

关于hibernate中映射中有many to one等外键关联时的问题的更多相关文章

  1. T-SQL中找出一个表的所有外键关联表

    二种方法(下例中表名为T_Work) 1.SQL查询系统表 SELECT 主键列ID=b.rkey ,主键列名=(SELECT name FROM syscolumns WHERE colid=b.r ...

  2. hibernate5(12)注解映射[4]一对一外键关联

    在实际博客站点中,文章内容的数据量非常多,它会影响我们检索文章其他数据的时间,如查询公布时间.标题.类别的等. 这个时候,我们能够尝试将文章内容存在还有一张表中,然后建立起文章--文章内容的一对一映射 ...

  3. Hibernate中映射一对一关联(按主键映射和外键映射)和组件映射

                                                        Hibernate中映射一对一关联(按主键映射和外键映射)和组件映射 Hibernate提供了两 ...

  4. Hibernate,关系映射的多对一单向关联、多对一双向关联、一对一主键关联、一对一外键关联、多对多关系关联

    2018-11-10  22:27:02开始写 下图内容ORM.Hibernate介绍.hibername.cfg.xml结构: 下图内容hibernate映射文件结构介绍 下图内容hibernate ...

  5. Hibernate 再接触 关系映射 一对一单向外键关联

    对象之间的关系 数据库之间的关系只有外键 注意说关系的时候一定要反面也要说通 CRUD 数据库之间设计 主键关联 单向的外键关联 中间表 一对一单向外键关联 Husband.java package ...

  6. Hibernate关系映射 一对一双向外键关联@OneToOne Annotation方式 双向关联和单向关联的区别

    首先还是来构造一个实际应用的场景,比如实体类车辆(Car),它具有以下属性:Id,品牌(brand),车牌(lisencePlate):实体类车牌(LisencePlate),它具有以下属性:Id,号 ...

  7. Hibernate关系映射 一对一双向外键关联@OneToOne Annotation方式

    首先还是来构造一个实际应用的场景,比如实体类车辆(Car),它具有以下属性:Id,品牌(brand),车牌(lisencePlate):实体类车牌(LisencePlate),它具有以下属性:Id,号 ...

  8. hibernate 关系映射之 单向外键关联一对一

    这里的关系指的是对象与对象之间的关系 注解方式单向关联一对一: //这个类描述的husband是一个对应一个wife的 import javax.persistence.Entity; import ...

  9. hibernate一对一双向外键关联

    一对一双向外键关联:双方都持有对方的外键关联关系. 主控方和一对一单向外键关联的情况是一样的,主要的差异表现为,被空方需要添加: @OneToOne(mappedBy="card" ...

随机推荐

  1. TortoiseSVN里checkout depth各选项的含义

    代表四种检出深度: 1.Fully recursive——全递归:检出完整的目录树,包含所有的文件或子目录.2.Immediate children,including folders——直接子节点, ...

  2. zlib编译不过(Error A2070)解决方法(转)

    原文转自 http://dearymz.blog.163.com/blog/static/2056574200871010027435/ 1.zlib是个很牛的东东,从http://www.zlib. ...

  3. PHP命令行执行程序php.exe使用及常用参数

    PHP命令行执行程序php.exe参数说明 -f <file>:以命令行方式运行指定的PHP文件,只要指定具体的PHP文件(带绝对路径),php.exe就可以执行PHP文件,所以这个参数单 ...

  4. 将本地访问ip映射成域名

    通过修改以下地址 C:\WINDOWS\system32\drivers\etc\hosts 加进你自己的如: 192.168.1.101  www.helloworld.com 配置nginx代理u ...

  5. Python基础-列表、元祖

    1. 列表.元组操作 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 定义列表 names = ['Alex',"Tenglan",'Eric ...

  6. Mongodb的学习整理(下)

    聚合 aggregate 聚合(aggregate)主要用于计算数据,类似sql中的sum().avg() 语法 db.集合名称.aggregate([{管道:{表达式}}]) 管道 管道在Unix和 ...

  7. 在Ubuntu/Centos使用 Let's Encrypt 证书部署 HTTPS的方法

    certbot地址 apache服务器(ubuntu环境): 1.获取软件包: $ sudo apt-get update $ sudo apt-get install software-proper ...

  8. MSSQL—列记录合并成一行

    在项目开发中,有时会碰到将列记录合并为一行的情况,例如根据地区将人员姓名合并,或根据拼音首字母合并城市等,下面就以根据地区将人员姓名合并为例,详细讲一下合并的方法. 首先,先建一个表,并添加一些数据, ...

  9. POJ 3624.Charm Bracelet-动态规划0-1背包

    Charm Bracelet Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 47876   Accepted: 20346 ...

  10. How to show only next line after the matched one?

    awk '/blah/{getline; print}' logfile