Hibernate JPA Sequence (non-Id)
Looking for answers to this problem, I stumbled upon this link
It seems that Hibernate/JPA isn't able to automatically create a value for your non-id-properties. The @GeneratedValue
annotation is only used in conjunction with @Id
to create auto-numbers.
The @GeneratedValue
annotation just tells Hibernate that the database is generating this value itself.
The solution (or work-around) suggested in that forum is to create a separate entity with a generated Id, something like this:
@Entity
public class GeneralSequenceNumber {
@Id
@GeneratedValue(...)
private Long number;
}
@Entity
public class MyEntity {
@Id ..
private Long id;
@OneToOne(...)
private GeneralSequnceNumber myVal;
}
How to use a sequence generator for a non ID field?
Check the value of result
returned from the generate method in SequenceControlNumber
class.
BTW check this response in this SO question : Hibernate JPA Sequence (non-Id)
JPA or Hibernate to generate a (non primary key) column value, not starting from 1
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.
Related Topics
How to Play .Wav Files with Java
Instantiating Generics Type in Java
Differencebetween Thread.Start() and Thread.Run()
Java.Lang.Runtimeexception: Uncompilable Source Code - What Can Cause This
Java 8: Difference Between Two Localdatetime in Multiple Units
How to Count the Number of Occurrences of an Element in a List
How to Override Class Variables in Java
Is There a Performance Difference Between a for Loop and a For-Each Loop
Java - Method Name Collision in Interface Implementation
How Will Java Lambda Functions Be Compiled
Splitting on Comma Outside Quotes
Get a Resource Using Getresource()
What Is a "Surrogate Pair" in Java