从具有顺序自动生成ID的Oracle数据库进行休眠保存后,实体的ID不同 [英] Id of entity is different after hibernate save from oracle database with sequence autogeneration id

查看:53
本文介绍了从具有顺序自动生成ID的Oracle数据库进行休眠保存后,实体的ID不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

具有ID的实体是根据oracle触发序列自动生成的.

Entity with id autogenerated from oracle trigger sequence.

@Entity
@Table(name = "REPORT", schema = "WEBPORTAL")
public class Report {
    private Integer id;
....


    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="report_sequence")
    @SequenceGenerator(name="report_sequence", sequenceName = "report_id_seq")
    @Column(name="REPORT_ID", unique = true, nullable = false)
    public Integer getId() {
        return id;
    }
....
}

服务

@Service("reportService")
public class ReportServiceImpl implements ReportService {
....

    @Transactional(readOnly=false)
    public void saveOrUpdate(Report report) {
        reportDAO.saveOrUpdate(report);
    }
}

DAO

@Repository
public class ReportDAOImpl implements ReportDAO {
....

    @Override
    public Report save(Report report) {
        try {
           Session session = sessionFactory.getCurrentSession();
           session.save(report);
        } catch (Exception e) {
           logger.error("error", e);
        }
        return report;
    }
}

然后,当我调用服务的saveOrUpdate并尝试获取实体的ID时,我得到的值与数据库中保留的值不同.具有自动生成功能的数据库中的值都可以.有什么建议吗?

And When I call service's saveOrUpdate and then try to reach id of entity I get different value than persisted in database. Values on database with autogeneration all is ok. Any suggestions?

reportService.saveOrUpdate(report);
System.out.println(report.getId());

张数:4150但保存在数据库中的ID为:84

prints: 4150 but saved id in database is: 84

注意::获取ID的目的在于,我希望通过级联来保存孩子.但是子级的外键在数据库中是不同的(我通过getId()获得的id的值).

NOTE: My purpose to get Id comes from that I wanted to save childs with cascade. But foreign key on child was different in database(the values of id that I get with getId()).

数据库中生成的ID加2.例如:80、82、84.

And Id generated in database is incremented by 2. EX: 80, 82, 84.

更新:

用于序列生成的Oracle触发器

Oracle trigger for sequence generation

CREATE OR REPLACE TRIGGER REPORT_ID_TRIG    
BEFORE INSERT ON WEBPORTAL.REPORT  
FOR EACH ROW   
BEGIN   
    SELECT report_id_seq.NEXTVAL  
    INTO :new.report_id  
    FROM dual;  
END;  

推荐答案

答案:触发器应检查id是否为空

ANSWER: Trigger should check if id is null

CREATE OR REPLACE TRIGGER REPORT_ID_TRIG
BEFORE INSERT ON WEBPORTAL.REPORT
FOR EACH ROW
WHEN (new.report_id is null)
BEGIN 
    SELECT report_id_seq.NEXTVAL
    INTO :new.report_id
    FROM dual;
END;

说明:
@GeneratedValue不仅是序列生成器.这是HiLo算法的一部分,当它第一次从数据库请求id时,将其乘以50(可以不同),因此接下来的50个新实体将被赋予id,然后是下一个请求数据库.这是为了减少对数据库的请求.
我从Java获得的数字是正确的数字,应该保存在报告中.

DESCRIPTION:
@GeneratedValue is not just a sequence generator. It's bit of HiLo algorithm.When it first requests id from database it multiplies it with 50(it can differ) and next 50 new entities will be given ids consequently, and than next request to database. This is to decrease request to database.
The numbers that I get from java was right numbers that should be saved on report.

没有id空值检查,Hibernate首先从数据库请求id,然后调用sequence.nextval.当休眠保持它(完成事务)时,数据库第二次调用sequence.next并将该值设置为数据库.因此,在ReportDetails上有报告的真实ID值,在Report ID上它是从数据库设置的ID.

Without id null value check Hibernate firstly requested for id from database and sequence.nextval called. When hibernate was persisting it(completing transaction) the database called sequence.next second time and set that value to database. So on ReportDetails there was true id value of report and on the Report id it was id set from database.

这篇关于从具有顺序自动生成ID的Oracle数据库进行休眠保存后,实体的ID不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆