Search code examples
javahibernatejava-moneyjsr354

Why is javax.money.CurrencyUnit not Serializable?


Why does javax.money.CurrencyUnit not extend from java.io.Serializable? All of its subtypes implement java.io.Serializable, and on top of that, if you want to use it in your hibernate mapping, then findbugs will stop you (quite correctly) because:

[INFO] Class com.mycompany.SiteEntity defines non-transient non-serializable instance field defaultCurrency [com.mycompany.SiteEntity] In SiteEntity.java
[INFO] Class com.mycompany.SiteEntity defines non-transient non-serializable instance field supportedCurrencies [com.mycompany.SiteEntity] In SiteEntity.java
[INFO] Class com.mycompany.UserEntity defines non-transient non-serializable instance field sessionCurrency [com.mycompany.UserEntity] In UserEntity.java

Does this mean that one must use the class JDKCurrencyAdapter in one's hibernate mapping? I'd much rather prefer to use the interface, but if it is not possible then I'll use the class.


Solution

  • Static checks against Serializable are completely unreliable, in both directions. The FindBugs warnings here are well-intentioned, but shouldn't stop you from using CurrencyUnit as you are now.

    A class can have a field

    Object aSerializableObject
    

    and be serializable, even though the static type of the field is not -- as long as it ensures that references placed in this field are serializable. So the static check against Serializable produces false negatives.

    It also produces false positives; implementing Serializable is no guarantee that instances will serialize without exception; it is merely a statement of design intent.

    Bottom line: while it masquerades as a static-typing feature, serializability is in reality a dynamic-typing feature. Static checks (whether within the code, such as <T extends Serializable>, or external checks, such as these FindBugs warnings) are merely hints as to where something might go wrong.