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. IPV6地址格式分析

    IPV6地址格式分析 IPv6的地址长度是128位(bit). 将这128位的地址按每16位划分为一个段,将每个段转换成十六进制数字,并用冒号隔开. 例如:2000:0000:0000:0000:00 ...

  2. IPv4地址分类及特征

    IPv4地址分类及特征 IP地址后斜杠和数字代表的意思 其中有这样一个IP地址的格式:IP/数字,例如:111.222.111.222/24 这种格式平时在内网中用的不多,所以一下子看不懂,最后查了资 ...

  3. [洛谷P3701]「伪模板」主席树

    题目大意:太暴力了,就不写了,看这儿 题解:对于每个$byx$的人,从源点向人连边,容量为此人的寿命. 对于每个手气君的人,从人向汇点连边,容量为此人的寿命. 对于每个$byx$的人与手气君的人,如果 ...

  4. [poj] 2618 popular cows

    原题 这是一个强连通分量板子题. a thinks b is popular 即为a到b有一条边,要求被所有牛popular的牛的个数. 所求为对图进行强连通分量缩点后,没有出度的强连通分量里的点数( ...

  5. WKWebview 和 WebViewJavascriptBridge

    WKWebview 和 WebViewJavascriptBridge https://www.cnblogs.com/L-vincen/p/6681435.html 链接在这里,有很多不错的文章,大 ...

  6. 转:Java NIO(3)

    要想讲清楚nio的原理和它的优点得先清楚Java应用程序的文件读写原理和虚拟内存的原理.Java文件读取原理可参见如下图: 当应用程序需要读取文件的时候,内核首先通过DMA技术将文件内容从磁盘读入内核 ...

  7. mysql创建用户后无法登陆

    创建用户后登陆失败的原因是存在匿名用户: root@controller:~# mysql -h localhost -uaa -ppassword ERROR 1045 (28000): Acces ...

  8. Kubernetes控制节点安装配置

    #环境安装Centos 7 Linux release 7.3.1611网络: 互通配置主机名设置各个服务器的主机名hosts#查找kubernetes支持的docker版本Kubernetes v1 ...

  9. Delphi 给结构体指针分配内存,用new(p),释放用dispose(p)

    来自:http://blog.163.com/zhangzhifeng688%40126/blog/static/1652627582010102261748481/ 给结构体指针分配内存  但在很多 ...

  10. validate插件实现表单效验(二)

    一款优秀的表单验证插件——validation插件 特点: l  内置验证规则:拥有必填.数字.email.url和信用卡号码等19类内置验证规则 l  自定义验证规则:可以很方便的自定义验证规则 l ...