I would like to describe such cases when we create problems for "future us" just by an accident. I will show how different Java data types can ease or increase the pain in supporting the application later. Most common pitfals and tricky corner cases you probably have never thought about.
9. Money Float &
Double
Problem
Developers usually have no idea how it is represented:
• 𝑒 = 2.718281828459045
• π = 3.141592653589793
• tan
π
2
= 1.633123935319537𝑬16
18. Money Float &
Double
Drill
Down
/**
* Get or create float value for the given float.
*
* @param d the float
* @return the value
*/
public static ValueFloat get(float d) {
if (d == 1.0F) {
return ONE;
} else if (d == 0.0F) {
// -0.0 == 0.0, and we want to return 0.0 for both
return ZERO;
}
return (ValueFloat) Value.cache(new ValueFloat(d));
}
23. Money Convert
to Integer
Drill
Down
@Embeddable
public class Amount implements Serializable {
private int rate;
@Transient
private final int scale;
public Amount() {
scale = 6;
}
public Amount(int rate, int scale) {
this.scale = scale;
setRate(rate);
}
…
24. Money Convert
to Integer
Summary
• It is better to keep precision closer to the number
• It is better when arithmetic just works
• It is better when equals and compareTo work
• int <*/+> int can exceed int (same with long)
• Consistency is almost always above performance
25. Money Solution BigDecimal
Precision and accuracy are known and adjustable
Arithmetic is included
Supported by JDK, JDBC, and etc
Performance is quite nice
31. Identity Overflow
Sucker
Punch
• Also, “some languages” cannot work with 53+ bits integer types
• In addition, “some languages” work with custom 32-bit integer types
32. Identity Overflow Summary
There is a difference between DB and API identity
• Always use integer types as identity for DB
• Always use text types as identity for API
• Avoid using 32- bit types as identity at all
Unless you are 99.9% sure
33. Identity UUID
• Are not guaranteed to be globally unique
• Not K-ordered
• In most of the cases are excessively big (128 bit)
• Can be the reason of a serious performance degradation
• Have different versions which may suite better or worse
• Strangely enough RDBMS rarely supports UUID/GUID data types
• Weird:
• Time based on 100-nanosecond intervals since 15th of October 1582
• Were invented/published around 1999
34. Identity UUID
Store as
String
• 16 bytes
UUID is 128-bit value
• 36 symbols – which is more than 2 times bigger
A96A0D4C-49D0-4431-B126-4C66688ADEF3
40. String Encoding
Java uses UTF-16 for String encoding
UTF-16 has symbol range: 0x0000..0x10FFFF
String uses char[] (byte[] in JDK9)
Char has range: 0x0000..0xFFFF
46. String JDBC vs
DB
Mapping DB specific types to JDBC
Some DB or driver exceptional cases
BLOB vs CLOB
Narrower DB encoding
47. String JDBC vs
DB
Mapping
public enum JDBCType implements SQLType {
CHAR(Types.CHAR),
VARCHAR(Types.VARCHAR),
LONGVARCHAR(Types.LONGVARCHAR),
...
BLOB(Types.BLOB),
CLOB(Types.CLOB),
...
NCHAR(Types.NCHAR),
NVARCHAR(Types.NVARCHAR),
LONGNVARCHAR(Types.LONGNVARCHAR),
NCLOB(Types.NCLOB),
48. String JDBC vs
DB
Mapping
• CHARACTER [(len)] or CHAR [(len)]
• VARCHAR (len)
• BOOLEAN
• SMALLINT
• INTEGER or INT
• DECIMAL [(p[,s])] or DEC [(p[,s])]
• NUMERIC [(p[,s])]
• REAL
• FLOAT(p)
• DOUBLE PRECISION
• DATE
• TIME
• TIMESTAMP
• CLOB [(len)] or CHARACTER LARGE OBJECT [(len)] or CHAR LARGE OBJECT [(len)]
• BLOB [(len)] or BINARY LARGE OBJECT [(len)]
52. String JDBC vs
DB
BLOB &
CLOB
• just bytes
Binary Large OBject
• just characters in your DB encoding
Character Large OBject
53. String JDBC vs
DB
Char &
NChar
• uses your DB encoding or no encoding
Char, Varchar, CLOB…
• uses specified encoding
NChar, NVarchar, NCLOB…
• does not have NBLOB
BLOB
54. String JDBC vs
DB
Cp1251 vs
Cp1252
Sometimes encoding does not matter much
Unless too smart drivers spoil it
Unless they are not compatible
56. String JDBC vs
DB
Solution
Losing data because of encoding is lame
If you expect some strange strings coming use N* types
Never forget that symbol is not a char/byte it may save you one day
Your JDBC driver can screw you
65. Date Time
Zone
Quiz #2
• Date… ehmm… JSON does not know what it is…
• Long is a bit of a problem for 53+ impotent integer types (now 41,
~140,000 years and we will cross the border)
• String as ISO 8601 is a lesser evil
66. Date Time
Zone
Solution
Use the same App/DB time zone
Check your DB driver to ensure conversion safety
Store timestamps as long: DB and API
Store timestamps as String: API
73. Date DST &
Magic
Quiz #2
It will happen: 31.12.2016 23:59:60 (UTC)
It had happened: 30.06.2015 23:59:60 (UTC)
Blame the Earth, and Moon, and Sun
Blame software developers
74. Date One Last
Thing
Date vs
Interval
Date is a tuple of year, month, day, hour, and etc.
Instant is a precise point on the timeline
75. Date One Last
Thing
Date vs
Interval
Date can be converted to Instant
Instant can be converted to Date
• even within a Chronology
However, “conversion rate” is not constant
76. Date Summary
• Use UTC as much as possible
• Keep in mind the difference between Date and Instant
• Think of Date/Instant interoperation as it was designed/used by
idiots
• 24*60*60*1000 is, basically, simplification. Quite harmful at times.
• Use proper date libraries – you wouldn’t want to reinvent it again.
• GMT is not yet another name for UTC, beware!