Achieving absolute ordering on JPA event-entities
up vote
0
down vote
favorite
I try to define immutable Event-Entites (Event Sourcing) using Java JPA/Hibernate and want those events to have an absolute ordering that already is defined right after object-creation, before any persistence has taken place (no distributed setup where one would need consensus)
We are using automatic auditing properties using @CreatedDate but I crossed that off my list since this is only populated during persistence.
I can think of 2 options:
- using a global database-sequence that is queried during object-creation
Long ordering = System.nanoTime()
any advice/idea appreciated.
java hibernate sorting jpa event-sourcing
add a comment |
up vote
0
down vote
favorite
I try to define immutable Event-Entites (Event Sourcing) using Java JPA/Hibernate and want those events to have an absolute ordering that already is defined right after object-creation, before any persistence has taken place (no distributed setup where one would need consensus)
We are using automatic auditing properties using @CreatedDate but I crossed that off my list since this is only populated during persistence.
I can think of 2 options:
- using a global database-sequence that is queried during object-creation
Long ordering = System.nanoTime()
any advice/idea appreciated.
java hibernate sorting jpa event-sourcing
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I try to define immutable Event-Entites (Event Sourcing) using Java JPA/Hibernate and want those events to have an absolute ordering that already is defined right after object-creation, before any persistence has taken place (no distributed setup where one would need consensus)
We are using automatic auditing properties using @CreatedDate but I crossed that off my list since this is only populated during persistence.
I can think of 2 options:
- using a global database-sequence that is queried during object-creation
Long ordering = System.nanoTime()
any advice/idea appreciated.
java hibernate sorting jpa event-sourcing
I try to define immutable Event-Entites (Event Sourcing) using Java JPA/Hibernate and want those events to have an absolute ordering that already is defined right after object-creation, before any persistence has taken place (no distributed setup where one would need consensus)
We are using automatic auditing properties using @CreatedDate but I crossed that off my list since this is only populated during persistence.
I can think of 2 options:
- using a global database-sequence that is queried during object-creation
Long ordering = System.nanoTime()
any advice/idea appreciated.
java hibernate sorting jpa event-sourcing
java hibernate sorting jpa event-sourcing
edited Nov 23 at 1:13
Aleksandr Semyannikov
556216
556216
asked Nov 22 at 16:40
hotzen
1,5691636
1,5691636
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
want those events to have an absolute ordering that already is defined
right after object-creation
The simpliest solution is like:
public class SomeEntity {
private LocalDateTime createdAt = LocalDateTime.now();
}
Of course it is possible that two objects will be created simultaneously and will have the same date, but it might be extremely hard to get.
A bit more complex - ordered by id if dates are equal and both objects are persisted. There may be indeterminacy if some of objects is not persisted yet, but if both are persisted - strict order is guaranteed:
public class SomeEntity implements Comparable<SomeEntity> {
private Long id;
private LocalDateTime createdAt = LocalDateTime.now();
@Override
public int compareTo(SomeEntity o) {
int result = createdAt.compareTo(o.createdAt);
if (result == 0) {
if (id != null && o.id != null) {
result = id.compareTo(o.id);
} else if (id != null) {
result = 1;
} else if (o.id != null) {
result = -1;
}
}
return result;
}
}
The most complex option but strict ordering is guaranteed: you can create counter service in your JVM and create events through factory, that will use that counter during event creation.
public class CounterService {
AtomicInteger counter = new AtomicInteger();
public int getNext() {
return counter.incrementAndGet();
}
}
public class SomeEntityFactory {
private CounterService counterService;
public SomeEntity create() {
return new SomeEntity(counterService.getNext());
}
}
public class SomeEntity {
private int order;
SomeEntity(int order) {
this.order = order;
}
}
Of course, this is example only, counter service might return BigInteger and be a web service, for instance. Or you can use a database sequence like a counter.
i am hesistant to use the wall-clock time (LocalDateTime.now()
).
– hotzen
Nov 23 at 13:15
theCounterService
would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?
– hotzen
Nov 23 at 13:16
There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to useLocalDateTime
? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?
– Aleksandr Semyannikov
Nov 23 at 13:28
@hotzen I changed code in the second solution a little.
– Aleksandr Semyannikov
Nov 23 at 13:48
i am hesistant because of time skew (even if ntp)
– hotzen
Nov 30 at 8:22
|
show 1 more comment
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435212%2fachieving-absolute-ordering-on-jpa-event-entities%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
want those events to have an absolute ordering that already is defined
right after object-creation
The simpliest solution is like:
public class SomeEntity {
private LocalDateTime createdAt = LocalDateTime.now();
}
Of course it is possible that two objects will be created simultaneously and will have the same date, but it might be extremely hard to get.
A bit more complex - ordered by id if dates are equal and both objects are persisted. There may be indeterminacy if some of objects is not persisted yet, but if both are persisted - strict order is guaranteed:
public class SomeEntity implements Comparable<SomeEntity> {
private Long id;
private LocalDateTime createdAt = LocalDateTime.now();
@Override
public int compareTo(SomeEntity o) {
int result = createdAt.compareTo(o.createdAt);
if (result == 0) {
if (id != null && o.id != null) {
result = id.compareTo(o.id);
} else if (id != null) {
result = 1;
} else if (o.id != null) {
result = -1;
}
}
return result;
}
}
The most complex option but strict ordering is guaranteed: you can create counter service in your JVM and create events through factory, that will use that counter during event creation.
public class CounterService {
AtomicInteger counter = new AtomicInteger();
public int getNext() {
return counter.incrementAndGet();
}
}
public class SomeEntityFactory {
private CounterService counterService;
public SomeEntity create() {
return new SomeEntity(counterService.getNext());
}
}
public class SomeEntity {
private int order;
SomeEntity(int order) {
this.order = order;
}
}
Of course, this is example only, counter service might return BigInteger and be a web service, for instance. Or you can use a database sequence like a counter.
i am hesistant to use the wall-clock time (LocalDateTime.now()
).
– hotzen
Nov 23 at 13:15
theCounterService
would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?
– hotzen
Nov 23 at 13:16
There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to useLocalDateTime
? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?
– Aleksandr Semyannikov
Nov 23 at 13:28
@hotzen I changed code in the second solution a little.
– Aleksandr Semyannikov
Nov 23 at 13:48
i am hesistant because of time skew (even if ntp)
– hotzen
Nov 30 at 8:22
|
show 1 more comment
up vote
1
down vote
want those events to have an absolute ordering that already is defined
right after object-creation
The simpliest solution is like:
public class SomeEntity {
private LocalDateTime createdAt = LocalDateTime.now();
}
Of course it is possible that two objects will be created simultaneously and will have the same date, but it might be extremely hard to get.
A bit more complex - ordered by id if dates are equal and both objects are persisted. There may be indeterminacy if some of objects is not persisted yet, but if both are persisted - strict order is guaranteed:
public class SomeEntity implements Comparable<SomeEntity> {
private Long id;
private LocalDateTime createdAt = LocalDateTime.now();
@Override
public int compareTo(SomeEntity o) {
int result = createdAt.compareTo(o.createdAt);
if (result == 0) {
if (id != null && o.id != null) {
result = id.compareTo(o.id);
} else if (id != null) {
result = 1;
} else if (o.id != null) {
result = -1;
}
}
return result;
}
}
The most complex option but strict ordering is guaranteed: you can create counter service in your JVM and create events through factory, that will use that counter during event creation.
public class CounterService {
AtomicInteger counter = new AtomicInteger();
public int getNext() {
return counter.incrementAndGet();
}
}
public class SomeEntityFactory {
private CounterService counterService;
public SomeEntity create() {
return new SomeEntity(counterService.getNext());
}
}
public class SomeEntity {
private int order;
SomeEntity(int order) {
this.order = order;
}
}
Of course, this is example only, counter service might return BigInteger and be a web service, for instance. Or you can use a database sequence like a counter.
i am hesistant to use the wall-clock time (LocalDateTime.now()
).
– hotzen
Nov 23 at 13:15
theCounterService
would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?
– hotzen
Nov 23 at 13:16
There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to useLocalDateTime
? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?
– Aleksandr Semyannikov
Nov 23 at 13:28
@hotzen I changed code in the second solution a little.
– Aleksandr Semyannikov
Nov 23 at 13:48
i am hesistant because of time skew (even if ntp)
– hotzen
Nov 30 at 8:22
|
show 1 more comment
up vote
1
down vote
up vote
1
down vote
want those events to have an absolute ordering that already is defined
right after object-creation
The simpliest solution is like:
public class SomeEntity {
private LocalDateTime createdAt = LocalDateTime.now();
}
Of course it is possible that two objects will be created simultaneously and will have the same date, but it might be extremely hard to get.
A bit more complex - ordered by id if dates are equal and both objects are persisted. There may be indeterminacy if some of objects is not persisted yet, but if both are persisted - strict order is guaranteed:
public class SomeEntity implements Comparable<SomeEntity> {
private Long id;
private LocalDateTime createdAt = LocalDateTime.now();
@Override
public int compareTo(SomeEntity o) {
int result = createdAt.compareTo(o.createdAt);
if (result == 0) {
if (id != null && o.id != null) {
result = id.compareTo(o.id);
} else if (id != null) {
result = 1;
} else if (o.id != null) {
result = -1;
}
}
return result;
}
}
The most complex option but strict ordering is guaranteed: you can create counter service in your JVM and create events through factory, that will use that counter during event creation.
public class CounterService {
AtomicInteger counter = new AtomicInteger();
public int getNext() {
return counter.incrementAndGet();
}
}
public class SomeEntityFactory {
private CounterService counterService;
public SomeEntity create() {
return new SomeEntity(counterService.getNext());
}
}
public class SomeEntity {
private int order;
SomeEntity(int order) {
this.order = order;
}
}
Of course, this is example only, counter service might return BigInteger and be a web service, for instance. Or you can use a database sequence like a counter.
want those events to have an absolute ordering that already is defined
right after object-creation
The simpliest solution is like:
public class SomeEntity {
private LocalDateTime createdAt = LocalDateTime.now();
}
Of course it is possible that two objects will be created simultaneously and will have the same date, but it might be extremely hard to get.
A bit more complex - ordered by id if dates are equal and both objects are persisted. There may be indeterminacy if some of objects is not persisted yet, but if both are persisted - strict order is guaranteed:
public class SomeEntity implements Comparable<SomeEntity> {
private Long id;
private LocalDateTime createdAt = LocalDateTime.now();
@Override
public int compareTo(SomeEntity o) {
int result = createdAt.compareTo(o.createdAt);
if (result == 0) {
if (id != null && o.id != null) {
result = id.compareTo(o.id);
} else if (id != null) {
result = 1;
} else if (o.id != null) {
result = -1;
}
}
return result;
}
}
The most complex option but strict ordering is guaranteed: you can create counter service in your JVM and create events through factory, that will use that counter during event creation.
public class CounterService {
AtomicInteger counter = new AtomicInteger();
public int getNext() {
return counter.incrementAndGet();
}
}
public class SomeEntityFactory {
private CounterService counterService;
public SomeEntity create() {
return new SomeEntity(counterService.getNext());
}
}
public class SomeEntity {
private int order;
SomeEntity(int order) {
this.order = order;
}
}
Of course, this is example only, counter service might return BigInteger and be a web service, for instance. Or you can use a database sequence like a counter.
edited Nov 23 at 13:48
answered Nov 22 at 17:25
Aleksandr Semyannikov
556216
556216
i am hesistant to use the wall-clock time (LocalDateTime.now()
).
– hotzen
Nov 23 at 13:15
theCounterService
would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?
– hotzen
Nov 23 at 13:16
There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to useLocalDateTime
? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?
– Aleksandr Semyannikov
Nov 23 at 13:28
@hotzen I changed code in the second solution a little.
– Aleksandr Semyannikov
Nov 23 at 13:48
i am hesistant because of time skew (even if ntp)
– hotzen
Nov 30 at 8:22
|
show 1 more comment
i am hesistant to use the wall-clock time (LocalDateTime.now()
).
– hotzen
Nov 23 at 13:15
theCounterService
would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?
– hotzen
Nov 23 at 13:16
There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to useLocalDateTime
? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?
– Aleksandr Semyannikov
Nov 23 at 13:28
@hotzen I changed code in the second solution a little.
– Aleksandr Semyannikov
Nov 23 at 13:48
i am hesistant because of time skew (even if ntp)
– hotzen
Nov 30 at 8:22
i am hesistant to use the wall-clock time (
LocalDateTime.now()
).– hotzen
Nov 23 at 13:15
i am hesistant to use the wall-clock time (
LocalDateTime.now()
).– hotzen
Nov 23 at 13:15
the
CounterService
would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?– hotzen
Nov 23 at 13:16
the
CounterService
would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?– hotzen
Nov 23 at 13:16
There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to use
LocalDateTime
? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?– Aleksandr Semyannikov
Nov 23 at 13:28
There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to use
LocalDateTime
? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?– Aleksandr Semyannikov
Nov 23 at 13:28
@hotzen I changed code in the second solution a little.
– Aleksandr Semyannikov
Nov 23 at 13:48
@hotzen I changed code in the second solution a little.
– Aleksandr Semyannikov
Nov 23 at 13:48
i am hesistant because of time skew (even if ntp)
– hotzen
Nov 30 at 8:22
i am hesistant because of time skew (even if ntp)
– hotzen
Nov 30 at 8:22
|
show 1 more comment
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435212%2fachieving-absolute-ordering-on-jpa-event-entities%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown