1

I'm working on a school project, building microservices to manage other microservices.

We're using Apache Tomee, Hibernate OGM with a MongoDB provider and Arquillian for testing. The servers we are managing run docker and messaging, in the form of tasks, between microservices is done using ActiveMQ and JMS. We also save these tasks to the database to process information later on.

Though, we have run into the following problem: Unless the database connection is destroyed and reconnected, a previously persisted entity will not be found.

Here is some code of the saving/deleting:

public void persist(Object entity) {
    em.getTransaction().begin();
    em.persist(entity);
    em.flush();
    em.getTransaction().commit();
}

public void deleteTask(String id) {
    em.getTransaction().begin();
    Task task = em.find(Task.class, id);
    if(task.getServer() != null && task.getServer().getTasks() != null) {
        task.getServer().getTasks().remove(task);
        em.merge(task.getServer());
    }

    if(task.getProject() != null) {
        // Stub for when tasks are added to the project
    }

    if(task.getImage() != null && task.getImage().getTasks() != null) {
        task.getImage().getTasks().remove(task);
        em.merge(task.getImage());
    }
    em.remove(task);
    em.getTransaction().commit();
}

As you can see in the above example, we also have to do extensive checking of the relations before truly deleting an entity. Somehow Hibernate does not relate.

These are our entities:

@Entity
public class Task {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;

    @NotNull
    @Enumerated(EnumType.STRING)
    private TaskType taskType;

    @ManyToOne
    @NotNull
    private Server server;

    @ManyToOne
    @Expose(serialize = false, deserialize = false)
    private Project project;

    @ManyToOne
    private Image image;

    @OneToOne
    private TaskResult taskResult; 
}

And the Image which is related as an example:

public class Image {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;

    @Size(min = 5, max = 100)
    private String name;

    @Size(min = 5, max = 200)
    private String dockerUrl;

    @Size(min = 1, max = 40)
    private String version;

    @OneToMany(mappedBy = "image")
    private List<Task> tasks;

    @ManyToOne
    private Project project;
}

And last but not least: Our persistence.xml

<persistence-unit name="dockingstationPu" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>

    <properties>
        <property name="hibernate.ogm.datastore.provider" value="mongodb" />
        <property name="hibernate.ogm.datastore.database" value="dockingstation" />
        <property name="hibernate.ogm.datastore.host" value="mongo.service.consul" />
        <property name="hibernate.ogm.datastore.document.association_storage" value="ASSOCIATION_DOCUMENT"/>
        <property name="hibernate.ogm.mongodb.association_document_storage" value="COLLECTION_PER_ASSOCIATION"/>
    </properties>
</persistence-unit>

If any other code or resource is needed to solve this, let me know. I have been trying my best to find a solution for some days now, but I can't find an answer anywhere.

  • so you persist an object, commit the transaction, then try a find() in a new transaction and it doesn't find it? and have you looked in MongoDB? That would at least show you where the problem is. I've done operations like that all of the time in my app using DataNucleus JPA + MongoDB without problem. – Neil Stockton May 04 '15 at 06:35
  • It does show up in the mongoVue (which I use for looking in the database), so that is the weird thing. I think it has something to do with hibernate, but I can't be sure. I indeed commit the transaction, but don't start one when I try to find one.. could that be the problem? – Mitchell Herrijgers May 04 '15 at 12:48
  • That shouldn't be needed; but the JPA impl I use logs what it does to try to find the object ... doesn't Hibernate? – Neil Stockton May 04 '15 at 12:49
  • 1
    Well, I decided to ditch Hibernate and use the DataNucleus JDO, works way better :) – Mitchell Herrijgers May 06 '15 at 19:45

0 Answers0