JPA或Hibernate生成一个(非主键)列值,而不是从1开始 [英] JPA or Hibernate to generate a (non primary key) column value, not starting from 1

查看:272
本文介绍了JPA或Hibernate生成一个(非主键)列值,而不是从1开始的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个可以生成列值的JPA / Hibernate(最好是JPA)注释,它不是主键,它不能从1开始。



从我看到的JPA不能用@GeneratedValue和@SequenceGenerator和@TableGenerator来做到这一点。或与其他任何东西。



我已经看到一个解决方案与一个额外的表,我发现它不是优雅的。



我可以使用Hibernate注释,因为我已经有了hibernate注释。 / p>

我想使用@Generated,但我无法使其工作,并且人们声称

pre code $ @Generated(GenerationTime.INSERT)
private private invoiceNumber; // invoice数字

更新:额外的要求,如果事务回滚,我们不能有差距在编号中。
任何人?

以下是我的工作原理 - 我们在服务中编写了所有代码。
这是实体:

pre $ @Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Registrant extends AbstractEntity {
// ....
private long invoiceNumber; // invoice number

@Entity
public static class InvoiceNumberGenerator {
@Id
@GeneratedValue
private int id;
私人长柜台;

public int getId(){
return id;
}

public void setId(int id){
this.id = id;
}

public long getCounter(){
return counter;
}

public void setCounter(long counter){
this.counter = counter;
}
}
}

然后我们有一项服务(实际上没有魔法,全部手动完成):

  public synchronized注册者保存(注册人注册人){
long counter = getInvoiceNumber();
registrant.setInvoiceNumber(counter);

返回registrantRepository.save(注册人);

$ b private long getInvoiceNumber(){
// mist:从另一张表中获取发票号码
long count = registrantInvoiceNumberGeneratorRepository.count();
if(count> 1){
throw new RuntimeException(:InvoiceNumberGenerator table has more than one row。Fix that);
}

Registrant.InvoiceNumberGenerator生成器;
if(count == 0){
generator = new Registrant.InvoiceNumberGenerator();
generator.setCounter(1000001);
generator = registrantInvoiceNumberGeneratorRepository.save(generator);
} else {
generator = registrantInvoiceNumberGeneratorRepository.findFirstByOrderByIdAsc();
}


long counter = generator.getCounter();
generator.setCounter(counter + 1);
registrantInvoiceNumberGeneratorRepository.save(generator);
return counter;

$ / code>

请注意 synchronized 方法 - 所以没有人可以得到相同的数字。



我不相信没有什么能够做到的自动化。


I want a JPA/Hibernate (preferably JPA) annotation that can generate the value of a column, that is not a primary key and it doesn't start from 1.

From what I have seen JPA cannot do that with @GeneratedValue and @SequenceGenerator and @TableGenerator. Or with anything else.

I have seen a solution with an extra table, which I find is not elegant.

I can live with a Hibernate annotation, because I already have hibernate annotations.

I want to use @Generated but I cannot make it work and people claim that it is possible.

@Generated(GenerationTime.INSERT)
private long invoiceNumber;//invoice number

Update: an extra requirement, if the transaction is rolled back, we can't have a gap in the numbering. Anyone?

解决方案

Here's what worked for me - we coded all of it in the service. Here's the entity:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Registrant extends AbstractEntity {
    //....
    private long invoiceNumber;//invoice number

    @Entity
    public static class InvoiceNumberGenerator {
        @Id
        @GeneratedValue
        private int id;
        private long counter;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public long getCounter() {
            return counter;
        }

        public void setCounter(long counter) {
            this.counter = counter;
        }
    }
}

And then we have a service that does the magic (actually there's no magic, all is done manually):

public synchronized Registrant save(Registrant registrant) {
    long counter = getInvoiceNumber();
    registrant.setInvoiceNumber(counter);

    return registrantRepository.save(registrant);
}

private long getInvoiceNumber() {
    //mist: get the invoice number from the other table
    long count = registrantInvoiceNumberGeneratorRepository.count();
    if(count > 1) {
        throw new RuntimeException(": InvoiceNumberGenerator table has more than one row. Fix that");
    }

    Registrant.InvoiceNumberGenerator generator;
    if(count == 0) {
        generator = new Registrant.InvoiceNumberGenerator();
        generator.setCounter(1000001);
        generator = registrantInvoiceNumberGeneratorRepository.save(generator);
    } else {
        generator = registrantInvoiceNumberGeneratorRepository.findFirstByOrderByIdAsc();
    }


    long counter = generator.getCounter();
    generator.setCounter(counter+1);
    registrantInvoiceNumberGeneratorRepository.save(generator);
    return counter;
}

Note the synchronized method - so that nobody can get the same number.

I can't believe there's nothing automatic that can do that.

这篇关于JPA或Hibernate生成一个(非主键)列值,而不是从1开始的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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