Closed ceefour closed 6 years ago
To add JScience support more than Unit needs supporting. I think that a heuristic type along the lines of PersistentEnum ought to be added for Measure (DecimalMeasure, DoubleMeasure, FloatMeasure, IntegerMeasure, LongMeasure, VectorMeasure) with the option of overriding the configured methods for customisation. A similar approach can be taken for Coordinates (Altitude, Height, LatLong etc) so that a single customisable user type could support them and Amount (including Time).
So - this could be generalised to a straightforward usertype for Unit and a heuristic type for Measurable.
Thank you..
Unit
can also be treated as heuristic "dynamic enum" type (a la PersistentCurrencyUnit
) and the implementation UserType
can be used for many things. However I still suggest for shortcuts for JScience/JSR275 (i.e. PersistentUnit
as subclass of the heuristic UserType) because these classes are widely used.
Commonality of 'dynamic enums' (but they're not Java Enum
s but custom classes, so PersistentEnum
cannot be used):
VARCHAR
in database. for example, a Unit<?>
(unknown dimension) due to dynamic nature of combined units, it's not feasible to use e.g. ENUM
typeENUM
in database for restricted schemas (i.e. Unit<Length>
, Unit<Temperature>
) ... In this case, another UserType for PostgreSQL (#14) would be good that persists to ENUM
instead of VARCHAR
If a heuristic UserType
implementation is used it means app developers can persist their own "dynamic enums" easily, without having to write their own UserType
every time. :+1: An example on top of my head is java.util.Locale
, and there's no PersistentLocale
in jadira...
Adding Measure
, Coordinate
, etc. would be even more awesome, since it builds upon the UserType unit (both VARCHAR
and ENUM
variants). BTW for Measure
, I would be more inclined to use ENUM
instead of VARCHAR
(but both should be supported), since most likely it'll be used to store a specific dimension, i.e. length, weight, etc. which means the units are restricted and can fit into ENUM
, which in ENUM
-supporting databases (like PostgreSQL) are much more efficient than VARCHAR
.
are there any updates about this? having jadira together with jscience would be a really nice feature.
Leaving this open as a potential future feature
This no longer makes sense, please support JSR 363 instead (it's about to reach Public Draft before the end of 2015, likely around JavaOne, first projects like Duke Award winning OpenHab/Eclipse SmartHome already started adopting 363, too) The JSR 363 EG and Spec Leads are happy to help.
Thanks, will take a look. Are you also involved in 363?
Indeed, I'm one of the Spec Leads;-) See https://jcp.org/en/jsr/detail?id=363
Werner, Having looked into this I think it will be tricky for a general solution. Its to do with the extensible nature of JSR 363's API compared with Hibernate's need to deal with concrete types. Happy to discuss further, there may be something that can be done around this with Heuristic or Reflection types.
@ceefour If you are interested in working towards a pr for this, I will assist as I am able
It's not really much more extensible than JSR 354 in its core types Unit or Quantity. There are use cases (e.g. UCUM parsers including those to JSON thaks to Opower) where generic types play practically no role, so you get down to just those two basic types similar to what's been done with JSR 354 (here or by Zalando) already. Happy to help or discuss possible solutions.
@chrisphe Is Jadira still actively developed? JSR 363 went final the same day as the last version of Jadira. Looks like there was no activity for a year now.
@keilw I never got around to looking at this, but would still like to so... left the issue open. Thanks for the nudge.
Actually, the safest and most future-proof option would be using Indriya 1.0 now ;-) https://github.com/unitsofmeasurement/indriya is a fully compliant TCK compatible "backport" of the next RI (for JSR 385, which is scheduled to finish about a year from now just in time for the biggest Metric System reform since the SI System was introduced in 1960) so you can use it now with JSR 363 and only have to update dependency numbers later for 385. Would that sound convenient for Jadira?
@keilw Thanks for the update. It seems that JSR363 had the shortest lifespan ever. :D
@ceefour Not at all compared to the average JSF JSRs https://en.wikipedia.org/wiki/JavaServer_Faces 2.0 and 2.1 were just a year apart! Or what we now see with JSR 383 and 384. Each meant to last only 6 months ;-D By using Indriya you can be sure to be future-proof both when it comes to the Unit API and underlying JDK version(s)
I've added an initial implementation for Indriya. Mostly I've been able to avoid using implementation rather than TCK classes, other than Units and Quantities @keilw Any way I can avoid these uses?
If additional SQL column types should be supported, please create those as new issues
@chrisphe Yes, you can call
QuantityFactory<Length> qfl = ServiceProvider.current().getQuantityFactory(Length.class);
Quantity<Length> oneMetre = qfl.create(1, METRE);
Which still uses the Units
class, but this can also be done via SPI
SystemOfUnits metricSystem = ServiceProvider.current().getSystemOfUnitsService().
getSystemOfUnits();
Unit<Length> metre = metricSystem.getUnit(Length.class);
As long as you're fine with the default (base) unit, this is the easiest way to retrieve it via the SPI.
For other units it is currently necessary to look it up from the set of units
Unit<?> metre;
SystemOfUnits metricSystem = ServiceProvider.current().getSystemOfUnitsService().
getSystemOfUnits();
for (Unit u: metricSystem.getUnits()) {
if ("m".equals(u.getSymbol()) {
metre = u;
break;
}
}
We might add a convenience method like getUnit(String key)
to SystemOfUnits
allowing to do this more easily for other units, but even with Lambdas some of those could be reduced to a line or two.
@keilw So, currently, I have this one line:
Quantities.getQuantity(val + " " + unit.getSymbol());
So, I'm still unclear how to obtain a Quantity when I only have a value and a unit (not the parameterized type of the quantity).
As far as I can see I need to know the class that corresponds to the Unit (which I don't have apriori).
@chrisphe Without the class, that's a good question. I don't think the API/SPI might work because QuantityFactory
is type-safe. I don't think there is a way around it right now.
We could think of something in 2.0 e.g. additional methods on ServiceProvider
. If you want propose something in https://github.com/unitsofmeasurement/unit-api/issues.
@keilw No problem, for now I've only supported Indriya. The old UoM reference implementation also provides the same method (in a similar package) so it wouldn't be massively painful to support it if someone needs that. JScience I will likely not adopt into Jadira (I assume you don't see a strong driver for that since its effectively deprecated by the subsequent JSRs I think?).
If you do support a non-type space creation of a quantity in the API/SPI, the implementation can be portable between UoM providers.
Proposed implementation :
https://github.com/soluvas/soluvas-framework/blob/master/jpa/src/main/java/org/soluvas/jpa/PersistentUnit.java
Dependency:
Optional dependency so that projects not requiring jscience do not need to depend on it.