This is based on ObjectBox v2.8.1.
ObjectBox supports a relatively limited list of built-in types. The list does not include any of the modern java.time
classes, but we can use the ObjectBox @Convert
annotation.
I think it is best to completely avoid the old and problematic Date
class, so this example converts LocalDateTime
values to longs (however, Date
is one of their built-in supported types):
import java.time.LocalTime;
import io.objectbox.annotation.Entity;
import io.objectbox.annotation.Id;
import io.objectbox.annotation.Convert;
import io.objectbox.converter.PropertyConverter;
@Entity
public class LocalTimeRange {
@Id
private long id;
@Convert(converter = LocalTimeConverter.class, dbType = Long.class)
private LocalTime opens;
@Convert(converter = LocalTimeConverter.class, dbType = Long.class)
private LocalTime closes;
public static class LocalTimeConverter implements PropertyConverter<LocalTime, Long> {
@Override
public LocalTime convertToEntityProperty(Long databaseValue) {
if (databaseValue == null) {
return null;
}
return LocalTime.ofSecondOfDay(databaseValue);
}
@Override
public Long convertToDatabaseValue(LocalTime entityProperty) {
if (entityProperty == null) {
return null;
}
long seconds = (entityProperty.getHour() * 60 * 60) +
(entityProperty.getMinute() * 60) +
entityProperty.getSecond();
return seconds;
}
}
public LocalTimeRange(Long id) {
this.id = id;
}
public LocalTimeRange(long id, LocalTime opens, LocalTime closes) {
this.id = id;
this.opens = opens;
this.closes = closes;
}
public LocalTimeRange() {
}
// getters and setters not shown
}
Now we can create and store a couple of test objects:
BoxStore store = MyObjectBox.builder().name("objectbox-demo-db").build();
Box<LocalTimeRange> box = store.boxFor(LocalTimeRange.class);
// start with no objects:
box.query().build().remove();
// add two objects:
LocalTimeRange ltrOne = new LocalTimeRange(1,
LocalTime.of(9, 30, 0), //9:30:00 (9:30am)
LocalTime.of(10, 15, 0));
box.put(ltrOne);
LocalTimeRange ltrTwo = new LocalTimeRange(2,
LocalTime.of(10, 05, 0),
LocalTime.of(11, 45, 0));
box.put(ltrTwo);
And then we can query the data store:
// this will find both objects:
LocalTime testTime = LocalTime.of(10, 10, 0);
// this will find the 2nd object
//LocalTime testTime = LocalTime.of(10, 20, 0);
// convert the localtime to seconds:
Long seconds = localTimeToSeconds(testTime);
List<LocalTimeRange> localTimeRanges = box.query()
.less(LocalTimeRange_.opens, seconds)
.greater(LocalTimeRange_.closes, seconds)
.build().find();
for (LocalTimeRange ltr : localTimeRanges) {
System.out.println(ltr.toString());
}
store.close();
---
private static long localTimeToSeconds(LocalTime lt) {
return (lt.getHour() * 60 * 60) +
(lt.getMinute() * 60) +
lt.getSecond();
}
The query operators are also limited in the types they can handle:
less(LocalTimeRange_.opens, seconds)
Here, seconds
is a long
- because there is no query operator which takes the Java type we want to use (LocalTime
).
You may want to refine my example, to ensure that test times which fall exactly on one of the boundary values are handled correctly (there is no "less than or equal to" query method, for example). You can build more sophisticated queries with equal()
, and()
, or()
, and so on.
(This approach handles LocalTime
to the nearest second. If you want sub-second precision, you would need to update the logic to include LocalTime
's support for nanoseconds.)