Fix Hibernate OGM by injecting some 'Morphia' ODM (2022.07.20)

From 2007 I have been using 'Hibernate Object/Relational Mapping' (ORM) with MySQL. I started a contract in 2015 at RS Components (RS) who wanted to use a NoSQL database 'Proof of Concept' (PoC). As RS were big (JBoss &) WildFly users we decided to deploy EJBs for access with Entities, using MongoDB as the NoSQL. I decided to use 'Hibernate Object/Grid Mapper' (OGM) and it worked extremely well. 

In August 2019 I started a project for a Publisher, again using MongoDB with Hibernate OGM 5.4.1.Final (December 2018). In October 2020 we investigated upgrading to Jakarta EE 9 version (WildFly 21.0.0.Final), trying to get OGM to work with Jakarta EE 9. Unfortunately "Hibernate was not maintained anymore"! I finally got confirmation from RedHat: https://hibernate.org/ogm/releases/5.4/

After a few failed attempts with 'EclipseLink' and the pure MongoDB Driver with BSON I think I've found the solution with 'Morphia' - Object-Directory Mapping. Morphia is a wrapper around the Java driver for MongoDB see: https://www.mongodb.com/languages/morphia

Using 'Morphia'

See the 'Quick Tour' as the example on: https://morphia.dev/morphia/2.3/quicktour.html with:
  • morphia-core-2.3.0-SNAPSHOT.jar
  • classgraph-4.8.147.jar
  • mongodb-driver-core-4.6.1.jar
  • mongodb-driver-sync-4.6.1.jar
  • bson-4.6.1.jar
Deployed on:
  • WildFly 26.1.1 - Jakarta EE 8 Full & Web Distribution
  • MongoDB 5.0.7
  • Gradle 7.5
  • Openjdk version 18.0.1
Built & Deployed by Gradle on WildFly
// EJB
final Datastore datastore = Morphia.createDatastore(MongoClients.create(), "goStopHandleDB");

Query<Motorcycle> queryMotorcycle =
   datastore.find(Motorcycle.class)
      .filter(Filters.and( 
         Filters.eq("manufacturer", "Moto Guzzi"),
         Filters.eq("model", "V85"),
         Filters.eq("modelType", "TT 850")));

LOGGER.info(">>>>> MotorcyclesEJB queryMotorcycleII count = {}", queryMotorcycleII.count());
LOGGER.info(">>>>> MotorcyclesEJB queryMotorcycleII = {}", queryMotorcycleII.iterator().toList());
// Entity
@Entity(value = "motorcycles", useDiscriminator = false)
@Indexes(@Index(options = @IndexOptions(name = "motorcycles")))
public class Motorcycle {

private static final long serialVersionUID = 1L;

private static final Logger LOGGER = LoggerFactory.getLogger(Motorcycle.class);

@Id
private ObjectId id;
private String manufacturer; 
private String model;
private String modelType;
private String typesOf;
private Date dateProductionStarted; 
private Date dateProductionEnded;

@Embedded
private Engine engine;
@Embedded
private Performance performance;
@Embedded
private ChassisBrakesSuspensionWheels chassisBrakesSuspensionWheels;
@Embedded
private DimensionsWeights dimensions;
@Embedded
private Transmission transmission;
@Embedded
private Instruments instruments;
@Embedded
private Electrics electrics;
@Embedded
private Set<Colour> colours;

@Embedded
private Set<com.gostophandle.entity.morphia.Accessory> accessories;

@Embedded
private Image image;
    // Setters & Getters ...
}
// Entity etc. 
@Entity(value = "engine", useDiscriminator = false)
@Indexes(@Index(options = @IndexOptions(name = "engine")))
public class Engine {
   // Setters & Getters ..
}
Terminal
>>>>> MotorcyclesEJB queryMotorcycle count = 2
>>>>> MotorcyclesEJB queryMotorcycle = [Motorcycle{id='62d578bdc8289aad7a775c41', manufacturer='Moto Guzzi', model='V85', modelType='TT 850', typesOf='Enduro', dateProductionStarted=Wed Jan 01 00:00:00 GMT 2020, dateProductionEnded=Wed Jan 01 00:00:00 GMT 2020, engine=Engine{type='Four-Stroke', displacement=0.0, cylinder=2.0, capacityUnit='cc', bore=0.0, boreMeasurement='mm', stroke=0.0, strokeMeasurement='mm', distribution='null', maxiumPowerHp=0.0, maxiumPowerKilowatt=0.0, maxiumPowerRpm=0.0, maximumTorque=0.0, maximumTorqueUnit='Nm', maximumTorqueRpm=0.0}, performance=Performance{topSpeedMph=0.0, topSpeedKph=0.0, accelleration30Mph=0.0, accelleration60Mph=0.0, accelleration100Mph=0.0, accelleration30Kph=0.0, accelleration60Kph=0.0, accelleration100Kph=0.0}, chassisBrakesSuspensionWheels=ChassisBrakesSuspensionWheels{frame='null', swingarm='null', absSystem='null', frontBrakes='null', rearBrakes='null', frontSuspension='null', rearSuspension='null', tyresFront='null', tyresRear='null', frontTyre='null', rearTyre='null', frontWheel='null', rearWheel='null', instrumentDisplayFunctions='null'}, dimensions=null, transmission=Transmission{clutch='null', clutchOperation='null', finalDrive='null', gearbox='null', transmissionType='null', primaryReduction=0.0, gearRatios1st=0.0, greaRatios2nd=0.0, gearRatios3rd=0.0, gearRatios4th=0.0, gearRatios5th=0.0, gearRatios6th=0.0}, instruments=Instruments{headlights='null', socket='null', ignitionSystem='null', instruments='null', tailLight='null', usbSocket='null'}, electrics=Electrics{ignition=''}, colours=[Colour{colour='null'}], accessories=[], image=Image{file='/Users/NOTiFY/IdeaProjects/GoStopHandle/images', url='/MotoGuzzi/2020/', png='gu9032270euk03-01-m.png', dimensionsWidth='1500', dimensionsHeight='1000'}}, Motorcycle{id='62d578bdc8289aad7a775c4d', manufacturer='Moto Guzzi', model='V85', modelType='TT 850', typesOf='Enduro', dateProductionStarted=Fri Jan 01 00:00:00 GMT 2021, dateProductionEnded=Fri Jan 01 00:00:00 GMT 2021, engine=Engine{type='Four-Stroke', displacement=0.0, cylinder=2.0, capacityUnit='cc', bore=0.0, boreMeasurement='mm', stroke=0.0, strokeMeasurement='mm', distribution='null', maxiumPowerHp=0.0, maxiumPowerKilowatt=0.0, maxiumPowerRpm=0.0, maximumTorque=0.0, maximumTorqueUnit='Nm', maximumTorqueRpm=0.0}, performance=Performance{topSpeedMph=105.0, topSpeedKph=0.0, accelleration30Mph=0.0, accelleration60Mph=0.0, accelleration100Mph=0.0, accelleration30Kph=0.0, accelleration60Kph=0.0, accelleration100Kph=0.0}, chassisBrakesSuspensionWheels=ChassisBrakesSuspensionWheels{frame='1', swingarm='2', absSystem='3', frontBrakes='4', rearBrakes='5', frontSuspension='6', rearSuspension='7', tyresFront='8', tyresRear='9', frontTyre='10', rearTyre='11', frontWheel='12', rearWheel='13', instrumentDisplayFunctions='14'}, dimensions=null, transmission=Transmission{clutch='1', clutchOperation='2', finalDrive='3', gearbox='4', transmissionType='5', primaryReduction=0.0, gearRatios1st=0.0, greaRatios2nd=0.0, gearRatios3rd=0.0, gearRatios4th=0.0, gearRatios5th=0.0, gearRatios6th=0.0}, instruments=Instruments{headlights='1', socket='2', ignitionSystem='3', instruments='4', tailLight='5', usbSocket='6'}, electrics=Electrics{ignition=''}, colours=[Colour{colour='Nero Etna'}], accessories=[], image=Image{file='/Users/NOTiFY/IdeaProjects/GoStopHandle/images', url='/MotoGuzzi/2021/', png='gu9032273eum01-01-m.webp', dimensionsWidth='1500', dimensionsHeight='1000'}}]

Conclusion

After upgrading to the latest version of 'morphia-core-2.3.0-SNAPSHOT' I had to make just two changes: 
  • Changing my Entities with "useDiscriminator = false" 
  • Add "@IndexOptions(name = ...". 

The use of 'Filters' queries have reduced the size of my previous Java code using ORM/OGM significantly.

My next task is to upgrade WildFly 26.1.1 with 'Preview EE 9.1'. This would not be possible unless I could have migrated to Morphia. There's a known 'bug' with JSF Mojarra 2.3.17.SP01 (in Jakarta EE 8) which causes an issue with PrimeFaces 'p:tabView'. 

After nearly three years I've finally resolved the Hibernate ORM & OGM 'end-of-life' problem. To migrate to 'Morphia' was only a few weeks and I had excelled support from Justin Lee (https://github.com/evanchooly).

'Morphia' is the old-fashioned term for morphine. It was an analgesic and narcotic drug obtained from opium and used medicinally to relieve pain. Morphia definitely solved my (ORM & OGM) pains!

Travel to Java & Kotlin

Java, lying between Sumatra and Bali, is a volcano-dotted island that’s at the geographic and economic center of Indonesia, and home to more than half its people. Java’s largest city is modern, sprawling Jakarta, the nation’s capital.

Kotlin is a Russian island, located near the head of the Gulf of Finland, 32 kilometres west of Saint Petersburg in the Baltic Sea. Kotlin separates the Neva Bay from the rest of the gulf.

"Code from two Islands" (C) 1991-2022 NOTiFY Ltd.