== persist(): the INSERT Hibernate sends (one bind per JSON column) sql> insert into product (attributes,dimensions,name,specs,tags) values (?,?,?,?,?) sql> update product set attributes=?,dimensions=?,name=?,specs=?,tags=? where id=? == what PostgreSQL stored (jsonb text) attributes = {"color": "red", "price": 19.90, "ratio": 0.5, "stock": 12, "active": true, "nested": {"k": [1, 2, 3]}, "nothing": null, "bigNumber": 3000000000} tags = ["lighting", "office"] dimensions = {"depthMm": 180, "widthMm": 180, "heightMm": 420} specs = {"material": "steel", "weightKg": 1.8, "certifications": ["CE", "RoHS"]} == loaded back in a new session: Java types of the Map values color -> String red price -> Double 19.9 ratio -> Double 0.5 stock -> Integer 12 active -> Boolean true nested -> LinkedHashMap {k=[1, 2, 3]} nothing -> null null bigNumber -> Long 3000000000 dimensions -> Dimensions[widthMm=180, heightMm=420, depthMm=180] specs -> steel, 1.8, [CE, RoHS] == Java null vs JSON null vs empty null-attrs | attributes=SQL NULL | tags=SQL NULL | dimensions=SQL NULL empty-attrs | attributes={} | tags=[] | dimensions=SQL NULL loaded null-attrs : attributes=null tags=null loaded empty-attrs : attributes={} tags=[]