现象描述:
在用hibernate做练习的时候用的是注解的形式配置pojo, 在操作po的时候出现了在数据库中插入数据主键不连续的现象,然后还发现数据库中自动产生了一张
表,觉得很纳闷儿,下面是插入操作的单元测试代码:
import com.sunsharing.dao.impl.SomeBodyDaoImpl;
import com.sunsharing.po.Address;
import com.sunsharing.po.SomeBody;
import com.sunsharing.service.Person02Service;
import com.sunsharing.service.SomeBodyService;
import org.hibernate.Session;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.junit.*;
import java.util.Set;
/**
* Created by baich on 2016/2/19.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml", "classpath:spring-hibernate.xml", "classpath:mvc-dispatcher-servlet.xml"})
public class SomeBodyTest {
@Autowired
private SomeBodyService someBodyService;
@Autowired
private SomeBodyDaoImpl someBodyDaoImpl;
@Test
public void insert() {
Session session = someBodyDaoImpl.getSessionFactory().openSession();
session.beginTransaction();
SomeBody someBody = new SomeBody();
someBody.setUserName("yangbo");
someBody.setGender("male");
someBody.setAge(20);
Address address = new Address();
address.setAddressDetail("huangshi");
//address.setAddressId(50);
Address address02 = new Address();
address02.setAddressDetail("leshan");
//address02.setAddressId(51);
someBody.getAddresses().add(address);
someBody.getAddresses().add(address02);
session.persist(address);
session.persist(address02);
session.persist(someBody);
Address address03 = new Address();
address03.setAddressDetail("beijing");
//address03.setAddressId(52);
session.persist(address03);
someBody.getAddresses().add(address03);
session.getTransaction().commit();
session.close();
}
}
SomeBody和Address是一对多映射关系,关系由SomeBody控制,程序功能是先持久化两个Address对象,然后将那两个Address对象设为SomeBody的Set<Address>属性的值,然后将SomeBody对象持久化,然后再持久化一个Address对象并将该对象添加到Set<Address>,提交事物。
问题:
为什么记录值不连续?
表的作用是什么?
原因,及解决办法:
经过同事帮助发现,原来如果实体类的主键生成策略注解成
@GeneratedValue(strategy = GenerationType.AUTO), 则主键由程序指定,故名思意,主键值由用户在程序中指定,如果用户不指定则由hibernate给自动指定,而hibernate的指定方式为,利用在数据库中自动生成的表,每次插入时根据中的记录值创建下一个id值,所有实体共享一个连续的序列。产生开头遇到的现象的原因是,插入前两个Address记录的时候是连续插入的(其间不涉及其他实体记录的插入),所以id值是连续的(1, 2),第三次的插入操作是SomeBody实体的插入,序列值3就分配给了SomeBody记录,然后再插入下一个Address对象时主键值就变成了4。
如果以后还有其他实体的记录插入,主键值就从5开始: