`
悲剧了
  • 浏览: 144373 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

hibernate引出的几个纠结事件分析

阅读更多
我们项目用的是ibatis,好久没写hibernate,手生,练习中发现几个以前没有多想的问题,跟大家分享下

首先:数据库字段设为自增长的时候,比如现在数据库里面的id是1,那么我继续插入,如果失败,下次我再插入结果就是3

我删除数据库所有数据,再次强势再插入结果是4

这个数据库是怎么回事,为什么插入失败,下次再插入,他会是3,删除所有数据,再次插入会是4呢?

以前一直用,还真没想过

其次:
多对多关系,一方是维护段,这个从逻辑上不好弄,值有一方维护着多对多的表。
如果要删除,还要通过那个表,加入数据也是,不然会报错。这个大家是怎么解决的,就这么将就的。

这里面的具体逻辑是怎么一个,为什么会这样设计

再有:两个多对多表,在实体间删除操作的时候,存在以下问题

两个实体如下
package com.jpa.bean;

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

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
@Entity
public class Brand {
	
	private String name;
	private Set<Person> persons=new HashSet<Person>();
	
	@Id
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@ManyToMany(cascade={CascadeType.PERSIST},mappedBy="brands")
	public Set<Person> getPersons() {
		return persons;
	}
	public void setPersons(Set<Person> persons) {
		this.persons = persons;
	}
	
	
	

}





package com.jpa.bean;

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

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
@Entity
public class Person {
	
	private int id;
	private Set<Brand> brands=new HashSet<Brand>();
	@Id
	@GeneratedValue
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	@ManyToMany(cascade={CascadeType.PERSIST})
	@JoinTable(inverseJoinColumns=@JoinColumn(name="person_id"),
			joinColumns=@JoinColumn(name="brand_id"))
	public Set<Brand> getBrands() {
		return brands;
	}
	public void setBrands(Set<Brand> brands) {
		this.brands = brands;
	}
	
}




/**
		
		em.getTransaction().begin();
		Brand b=em.getReference(Brand.class, "ANTA");
		
		Person p=em.getReference(Person.class, 7);
		p.getBrands().remove(b);
		em.remove(p);
	
		em.getTransaction().commit();


以上操作部会有问题,当Brand不是查询出来的时候,是自己new的
Brand b=new Brand();
b.setName("ANTA");
那么就会报错,这是为什么?
我的分析是Person p=em.getReference(Person.class, 7);得到的代理,你直接通过p.getBrands().remove(b);并不能接触他们的关系

测试把Person p=em.find(Person.class, 7);
解决问题

欢迎大家来讨论

分享到:
评论
30 楼 悟⑤道 2011-06-12  
gen30 写道
悲剧了 写道


我删除数据库所有数据,再次强势再插入结果是4

这个数据库是怎么回事,为什么插入失败,下次再插入,他会是3,删除所有数据,再次插入会是4呢?

以前一直用,还真没想过




delete清表数据,是不会重置id的吧,
截短表才会重置id;
truncate TABLE tabname;

就是
29 楼 qq346 2011-05-01  
使用new产生的对象并没有被持久化,所以会出错,对于代理这个问题你p.getBrands().remove(b)这个已经发出语句了却不能解除级联关系,不解,继续等待讨论
28 楼 qq346 2011-05-01  
id的问题确实是那么回事,偶也不知道怎么解决
27 楼 Jclick 2011-04-29  
kjj 写道
Jclick 写道
还有一个问题就是对于枚举类型的映射。也不知道是hibernate的问题还是我的问题。搞的我焦头烂额。在拼接Hql语句的时候,用到了setParameter(objs, types);当Object[] 包含枚举类型的时候,Type[]中没法映射,我试了好久都没有解决!重写UserType依旧不好使。。。哎~~纠结!


枚举默认是按照索引存储的 比如 0,1,2............

我自然知道是按照索引存储的,但是我的需求场景是这样的:
public PageBean getListForPage(final Object info,final String conditionHQL, final int currentPage, final Object[] objs, final Type[] types) {
//		HibernateTemplate hibernateTemplate = getHibernateTemplate()executeFind;
		List list = hibernateTemplate.executeFind(new HibernateCallback() {   
			public Object doInHibernate(Session session)   
				throws HibernateException, SQLException {  
				//创建HQL语句
				Query query;
				String hql = getHQL(info, conditionHQL);
				if(objs == null || types == null){
					query = session.createQuery(hql);
				}else{
					query = session.createQuery(hql).setParameters(objs, types);
				}
				query.setFirstResult((currentPage-1)*Constant.MAX_RESULTS);
				query.setMaxResults(Constant.MAX_RESULTS);
				List list = query.list();
				
				return list;
			}

		});


上边是方法的一段。如果hql语句中用到了枚举类型的。比如性别。那Type[]中应该怎么写?难道是Hibernate.Integer.显然是不对的。而我用成Hibernate.serializable(serializableClass)
Hibernate.custom(userTypeClass),竟然默认选择的全是枚举的第一个。求解释。。。。。。。。。
26 楼 qiangailei 2011-04-29  
因为你的操作虽然失败,但也操作到了数据库,所以自增长也算了一次。
25 楼 iceside 2011-04-29  
删除表数据采用trucate tablename,自增字段将重置,hibernate主键策略如果采用increment应该可以实现lz要求的每次都取当前表最大值的下一个值的要求,即主键完全按顺序来
24 楼 kjj 2011-04-28  
Jclick 写道
还有一个问题就是对于枚举类型的映射。也不知道是hibernate的问题还是我的问题。搞的我焦头烂额。在拼接Hql语句的时候,用到了setParameter(objs, types);当Object[] 包含枚举类型的时候,Type[]中没法映射,我试了好久都没有解决!重写UserType依旧不好使。。。哎~~纠结!


枚举默认是按照索引存储的 比如 0,1,2............
23 楼 van3312 2011-04-28  
楼主之前没用过hibernate的吧,哎,这都不是问题,自己没理解
22 楼 gen30 2011-04-28  
悲剧了 写道


我删除数据库所有数据,再次强势再插入结果是4

这个数据库是怎么回事,为什么插入失败,下次再插入,他会是3,删除所有数据,再次插入会是4呢?

以前一直用,还真没想过




delete清表数据,是不会重置id的吧,
截短表才会重置id;
truncate TABLE tabname;
21 楼 Jclick 2011-04-28  
还有一个问题就是对于枚举类型的映射。也不知道是hibernate的问题还是我的问题。搞的我焦头烂额。在拼接Hql语句的时候,用到了setParameter(objs, types);当Object[] 包含枚举类型的时候,Type[]中没法映射,我试了好久都没有解决!重写UserType依旧不好使。。。哎~~纠结!
20 楼 悲剧了 2011-04-28  
palmer 写道
无盐以对

id的问题和 hibernate 没有关系。

new Brand, remove  是基本的 Object的状态的问题。

不想贬低。。。不过这是基本概念, 看书应该细致一点。


我没说id 跟hibernate有关系

原文是这样的:
首先:数据库字段设为自增长的时候,比如现在数据库里面的id是1,那么我继续插入,如果失败,下次我再插入结果就是3

我删除数据库所有数据,再次强势再插入结果是4

这个数据库是怎么回事,为什么插入失败,下次再插入,他会是3,删除所有数据,再次插入会是4呢?

以前一直用,还真没想过






19 楼 yangzh_999 2011-04-28  
这个数据库暂时估计是oracle
hibernate配置文件中主键用的估计是oracle中的sequence

当操作主键一次,主键ID会自增一次,不论是操作增加还是查询,报错报错。所以会出现没增添一次就会增加,如果查询需要不增加主键需要查询临时表dual
18 楼 palmer 2011-04-28  
无盐以对

id的问题和 hibernate 没有关系。

new Brand, remove  是基本的 Object的状态的问题。

不想贬低。。。不过这是基本概念, 看书应该细致一点。
17 楼 kjj 2011-04-27  
全删怎么执行sql的, delete from tablename::??
16 楼 悲剧了 2011-04-27  
抛出异常的爱 写道
自定义主建生成策略.

比如 select max(id) +1 from dul;


这个触发是每次插入数据,不管失败与否,看来基本明白了是怎么回事

哥们能把第二个问题给解释下吗
15 楼 悲剧了 2011-04-27  
nakupanda 写道
刚查了一下资料, 很多人说mysql的自增字段不会随事务回滚的..

"
auto_increment,作为MySQL内部自增机制实现,其按一定规则自动实现自增,并且不可回朔,即使回滚,如delete般,ID已经自增过,只会继续增长,不可能跟着回滚和删除操作而减小,否则就不叫自增了。
不仅MySQL,Oracle数据库亦然。
"
http://bbs.phpchina.com/viewthread.php?tid=188731&rpid=1573813&ordertype=0&page=1#pid1573813


原来如此。谢了
14 楼 nakupanda 2011-04-27  
刚查了一下资料, 很多人说mysql的自增字段不会随事务回滚的..

"
auto_increment,作为MySQL内部自增机制实现,其按一定规则自动实现自增,并且不可回朔,即使回滚,如delete般,ID已经自增过,只会继续增长,不可能跟着回滚和删除操作而减小,否则就不叫自增了。
不仅MySQL,Oracle数据库亦然。
"
http://bbs.phpchina.com/viewthread.php?tid=188731&rpid=1573813&ordertype=0&page=1#pid1573813
13 楼 抛出异常的爱 2011-04-27  
自定义主建生成策略.

比如 select max(id) +1 from dul;
12 楼 悲剧了 2011-04-27  
pk3589 写道
悲剧了 写道
我们项目用的是ibatis,好久没写hibernate,手生,练习中发现几个以前没有多想的问题,跟大家分享下

首先:数据库字段设为自增长的时候,比如现在数据库里面的id是1,那么我继续插入,如果失败,下次我再插入结果就是3

我删除数据库所有数据,再次强势再插入结果是4

这个数据库是怎么回事,为什么插入失败,下次再插入,他会是3,删除所有数据,再次插入会是4呢?

以前一直用,还真没想过




首先的这个问题 我感觉这个是正常的 因为你在插入数据之前 hibernate先去取得下一个主键值 这样自增序列的值肯定会增加一个值  没有什么大惊的 所以当你插入失败的时候序列值通用会自增
。。。。。。。。

插入前去取值,属于查询出这个值,有影响吗?如果有影响,那么我查询这个主键值,查询后插入就会出现问题。这种查询在使用中很多,
那么这个自增长岂不是不能查询了,查询了后面的插入就会有问题

不知道我的理解对不对?
11 楼 pk3589 2011-04-27  
悲剧了 写道
我们项目用的是ibatis,好久没写hibernate,手生,练习中发现几个以前没有多想的问题,跟大家分享下

首先:数据库字段设为自增长的时候,比如现在数据库里面的id是1,那么我继续插入,如果失败,下次我再插入结果就是3

我删除数据库所有数据,再次强势再插入结果是4

这个数据库是怎么回事,为什么插入失败,下次再插入,他会是3,删除所有数据,再次插入会是4呢?

以前一直用,还真没想过




首先的这个问题 我感觉这个是正常的 因为你在插入数据之前 hibernate先去取得下一个主键值 这样自增序列的值肯定会增加一个值  没有什么大惊的 所以当你插入失败的时候序列值通用会自增
。。。。。。。。

相关推荐

    hibernate源码分析过程

    Hibernate 源码分析过程 Hibernate 是一个基于 Java 的 ORM(Object-Relation Mapping)框架,允许开发者使用面向对象的方式与关系数据库交互。在本文中,我们将对 Hibernate 的源码进行深入分析,并探讨其核心特性...

    Hibernate源代码分析

    Hibernate源代码分析 在 Hibernate 框架中,SessionFactory 和 ConnectionProvider 是两个非常重要的组件,了解它们的实现机制对于深入了解 Hibernate 的工作原理具有重要意义。本文将通过分析 Hibernate 的源代码...

    hibernate源码分析一[启动过程]

    在深入探讨Hibernate框架的启动过程之前,我们首先需要了解几个核心的概念和类,它们是Hibernate启动流程的基石。 ### 1. 关键类与接口 #### Environment类 `Environment`类扮演着系统环境变量的关键角色,它定义...

    hibernate的第一个例子

    **描述分析:**描述提到这是一个超级简单的例子,包含一个持久化对象(通常是Java类,对应数据库中的表)、一个辅助类(可能是配置或者工具类,帮助操作数据库)以及一个测试类(用于验证代码功能)。这个例子特别...

    hibernate事件 刷新事件.zip

    在Java的持久化框架Hibernate中,事件监听机制是其核心特性之一,它允许开发者在特定的数据操作前后执行自定义逻辑。这里的"hibernate事件 刷新事件.zip"资源可能包含了关于如何理解和应用Hibernate中的刷新事件...

    hibernate源码分析

    **Hibernate源码分析** Hibernate,一个著名的开源Java对象关系映射(ORM)框架,通过将Java对象和数据库表之间的映射关系自动化,极大地简化了数据访问层的开发工作。本篇将深入探讨Hibernate的源码,揭示其执行...

    Hibernate源码解析(一)

    Hibernate是由 Gavin King 创建的一个开源项目,它提供了一种在Java应用中持久化对象到关系数据库的解决方案。通过ORM,Hibernate将对象模型与关系数据库模型进行映射,使得开发人员可以使用面向对象的方式来处理...

    Hibernate实践例子程序

    一个最简单的Hibernate project(不涉及Struts, Tomcat, XDoclet,JBoss等东东)必须的几个东东: 1. Hibernate工具包。 2. JDBC数据库连接驱动。以mysql为例,mysql-connector-java-3.1.×-bin.jar。 3. 配置...

    Hibernate二级缓存配置与分析

    学习hibernate的必备,提供一个简易的流程图,方便记忆和查找

    Ibatis和Hibernate的分析比较

    首先,Hibernate是一个全面的对象关系映射框架,它简化了Java应用程序与数据库之间的交互。通过Hibernate,开发者可以用面向对象的方式处理数据,而无需直接编写SQL语句。Hibernate的核心组件包括Configuration对象...

    Hibernate 配置各种数据库

    Hibernate 是一个基于 Java 的持久层框架,提供了一个抽象的数据访问层,能够与多种数据库进行集成。在 Hibernate 的配置文件中,我们可以配置不同的数据库连接,包括驱动程序、URL 等信息。 配置 Hibernate 连接...

    Hibernate入门到精通

    Hibernate 是一个基于Java的ORM(Object-Relational Mapping,对象关系映射)框架,它提供了一种简洁高效的方式来访问和操作关系数据库。下面是 Hibernate 的主要知识点: Hibernate 简介 Hibernate 是一个开源的...

    优化Hibernate性能的几点建议

    ### 优化Hibernate性能的几点建议 ...总之,通过上述几个方面的优化措施,可以显著提高基于Hibernate构建的应用程序的性能。在实际应用中,还需要结合具体的业务场景和技术栈来灵活调整这些策略。

    Hibernate-extensions 完整安装包

    Hibernate-Extensions能够自动记录和打印执行的SQL语句,这对于调试和性能分析非常有帮助。开发者可以通过配置开启或关闭这一功能,以便在需要时查看SQL详情,找出潜在的性能瓶颈。 四、时间戳更新 在数据库操作中...

    Hibernate源码解析(三)

    在本篇中,作者聚焦于几个关键的组件和机制,帮助读者理解 Hibernate 如何高效地管理和操作数据库。 首先,文章可能会涉及Hibernate的核心接口`Session`。`Session`是Hibernate工作流程中的重要角色,它负责持久化...

    Hibernate入门案例源码

    在MyEclipse和Eclipse中,配置Hibernate通常包括以下几个步骤: 1. 添加Hibernate库:你需要导入Hibernate的jar文件或者通过Maven/Gradle等构建工具管理依赖。 2. 配置Hibernate:创建`hibernate.cfg.xml`配置文件,...

    hibernate-release-5.2.10

    关于Hibernate的知识点涵盖以下几个方面: 1. **实体管理**:Hibernate通过@Entity注解将Java类映射为数据库表,通过@Id指定主键,使得对象可以直接对应到数据库记录。 2. **配置**:Hibernate的配置文件(如...

    Hibernate使用指南

    使用 Hibernate 的步骤主要包括以下几个步骤: * 导入 jar 包:在项目中添加 Hibernate 的 jar 包,以便使用 Hibernate。 * 添加配置文件:在项目的 src 目录下添加 hibernate.cfg.xml 配置文件,以便配置 ...

    hibernate源码分析一_启动过程_

    **hibernate源码分析:启动过程** 在深入探讨Hibernate启动过程之前,首先需要了解Hibernate是什么。Hibernate是一个开源的对象关系映射(ORM)框架,它为Java开发人员提供了一种在Java应用程序中操作数据库的方式...

    hibernate3.zip 包含hibernate3.jar

    11. **事件监听器**:Hibernate允许注册事件监听器,对持久化对象的各种操作(如保存、更新、删除等)进行拦截和自定义处理。 以上就是`hibernate3.jar`中所包含的关键知识点。理解并熟练使用这些概念,可以帮助...

Global site tag (gtag.js) - Google Analytics