Hibernate PostgreSQL与自动生成的增量代码字段有什么混乱?

时间:2016-04-28 15:59:10

标签: java hibernate postgresql

Hibernate在jobLifeTime实体的现有数据库中创建了表,但是它给第一个记录自动生成的代码以8781开头,而不是0.这个表有其他对象的外键(scraperTask),在jobLifeTime之前存储在DB中实体对象,并给hibernate一个代码8780到scraperTask记录(这个清楚因为带有scraperTask的表已经有了一些记录)。

为什么hibernate使用来自scraperTask.code的jobLifeTime.code的增量计数?

更新 看起来Hibernate或PostgreSQL对两个表主键使用一个数字序列。这是正确的行为吗?

这里有来自数据库表的java类和截图:

jobLifeTime table - job_chron_stg

@Entity
@Table(name="job_chron_stg", indexes = {  @Index(name = "job_life_time_code_hidx", columnList = "code"),
        @Index(name = "job_life_time_job_id_hidx", columnList = "job_id")})
public class JobLifeTime {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)   
    private Long code;
    @Column(name="job_id", length=24)
    private String targetJobCode;
    @ManyToOne()
    private ScraperTask scraperTask;
    @Column(name="salary_low")
    private Integer salaryMin;
    @Column(name="salary_high")
    private Integer salaryMax;
    @Column(name="scrape_timestamp")
    private Date scrapeTimestamp;
    @Column(name="remove_timestamp")
    private Date removeTimestamp;

    public JobLifeTime(){}

    public JobLifeTime(Element node, ScraperTask scraperTask){
        targetJobCode = node.attr("data-jk");
        this.scraperTask = scraperTask;
        salaryMin = scraperTask.getSalaryMin();
        salaryMax = scraperTask.getSalaryMax();
        scrapeTimestamp = new Date();       
    }
//getters-setters
}

scraperTask类

@Entity
@Table(indexes = { @Index(name = "scraper_task_code_hidx", columnList = "code"),
        @Index(name = "task_start_at_hidx", columnList = "task_start_at")})
public class ScraperTask {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long code;
    @Column(name="task_start_at")
    private Date taskStartAt;
    private Date taskCompleteAt;
    private String description;
    @Transient
    private Integer salaryMin;
    @Transient
    private Integer salaryMax;
    //@Transient
    private Integer websiteJobsNumber;
    @Transient
    private String firstResponse;
    //@Transient
    //private Integer processedNodes;
    //@Transient
    private Boolean doneSuccessfully;
    @Transient
    private List<JobLifeTime> scrapedJobLifeTimeList;
    @Transient
    private List<Job> scrapedJobList;
    @Transient
    private KeywordsEntity keywordsEntity;
    @Transient
    private String category;

    protected ScraperTask(){
    }

    public ScraperTask(String uriString, Integer salaryMin, Integer salaryMax){
        description = uriString;
        taskStartAt = new Date();
        this.salaryMin = salaryMin;
        this.salaryMax = salaryMax;
        websiteJobsNumber=0;
        //processedNodes = 0;
        doneSuccessfully = false;
        scrapedJobLifeTimeList = new LinkedList<JobLifeTime>();
        scrapedJobList = new LinkedList<Job>();
    }
//getters-setters
}

2 个答案:

答案 0 :(得分:1)

如果要控制生成的值,请使用Postgresql序列对象并在实体对象中正确声明它。

也就是说,内部的,自动生成的主键不应该关心值是什么,因为在大多数情况下,它们不应该暴露在应用程序之外,而应该只用于外键(即,而不是在许多远程表中复制多部分PK)。使用序列号缓存,无法保证间隙不存在或者值严格按顺序排列(例如,不同的数据库连接可能缓存了不同的值,但您可能不知道每个插入使用哪个连接,因此无法保证严格增加值)

答案 1 :(得分:0)

您是否尝试截断jobLifeTime表。这张表还没有正确的记录。

TRUNCATE TABLE jobLifeTime