The collections in my entities don't get persisted, whether it's a simple collection or association.
I'm using OGM with mongodb.
For an example of the problem consider the following entities:
@Entity
class Document {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Type(type = "objectid")
String id;
String name;
@ElementCollection
Set<String> names;
Document() {
this.names = new HashSet<>();
}
Document(String name) {
this();
this.name = name;
}
}
@Entity
class ChildDocument {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Type(type = "objectid")
String id;
String name;
ChildDocument() {}
ChildDocument(String name) {
this.name = name;
}
}
class ParentDocument {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Type(type = "objectid")
String id;
int count;
@OneToMany(cascade = CascadeType.ALL)
@AssociationStorage(AssociationStorageType.IN_ENTITY)
List<ChildDocument> kids = new LinkedList<>();
}
The following setup:
final StandardServiceRegistryBuilder registryBuilder = new StandardServiceRegistryBuilder()
.applySetting(OgmProperties.ENABLED, true)
.applySetting(AvailableSettings.TRANSACTION_COORDINATOR_STRATEGY, "jta")
.applySetting(AvailableSettings.JTA_PLATFORM, "JBossTS")
.applySetting(OgmProperties.DATASTORE_PROVIDER, MongoDB.DATASTORE_PROVIDER_NAME)
.applySetting(OgmProperties.DATABASE, "testdb")
.applySetting(OgmProperties.CREATE_DATABASE, "true");
final StandardServiceRegistry registry = registryBuilder.build();
final MetadataSources sources = new MetadataSources(registry);
sources.addAnnotatedClass(Document.class);
sources.addAnnotatedClass(ChildDocument.class);
sources.addAnnotatedClass(ParentDocument.class);
final SessionFactory sessionFactory = sources.buildMetadata().getSessionFactoryBuilder()
.unwrap(OgmSessionFactoryBuilder.class)
.build();
And this short program:
Document document1 = new Document("one");
Document document2 = new Document("two");
document2.names.add("one.one");
document2.names.add("one.two");
ParentDocument parent = new ParentDocument();
parent.count = 2;
parent.kids.add(new ChildDocument("one"));
parent.kids.add(new ChildDocument("two"));
final Session session = sessionFactory.openSession();
session.save(document1);
session.save(document2);
session.save(parent);
session.close();
sessionFactory.close();
The testdb
now contains 3 collections: Document
, ChildDocument
and ParentDocument
.
ChildDocument
documents are correct as they only need to have the _id
and name
Document
documents also contain only the _id
and name
, the names
collection is missingParentDocument
only the _id
and count
are persisted but the reference to the kids is missing even though the ChildDocuments
are createdWhat am I doing wrong?
Thanks
Hibernate OGM under the hood execute some optimizations and therefore commands are not execute immediately on the db (usually).
When using Hibernate OGM you should still use transaction demarcation for your operations:
final Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(document1);
session.save(document2);
session.save(parent);
session.getTransaction().commit();
session.close();
This is explained in the documentation: http://docs.jboss.org/hibernate/ogm/5.0/reference/en-US/html/ch11.html#transactions
Note that using session.flush()
before session.close()
would work as well in this case.