一尘不染

JPA或Hibernate生成(非主键)列值,而不是从1开始

hibernate

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

从我看到的内容来看,JPA无法使用@GeneratedValue和@SequenceGenerator和@TableGenerator做到这一点。或其他。

我看到了一个带有额外表的解决方案,但我发现它并不优雅。

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

我想使用@Generated,但是我无法使用它,人们声称这是可能的。

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

更新:一项额外要求,如果交易回滚,我们在编号上不能有空白。任何人?


阅读 397

收藏
2020-06-20

共1个答案

一尘不染

这是对我有用的-我们在服务中对所有代码进行了编码。这是实体:

@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;
        }
    }
}

然后,我们有一个执行魔术的服务(实际上没有魔术,所有操作都是手动完成的):

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;
}

注意synchronized方法-这样没人能得到相同的号码。

我不敢相信没有自动装置可以做到这一点。

2020-06-20