I had always counted on EntityManager’s persist() method to immediately insert entities. I would rely on this when writing database integration tests - I’d persist some records, then test my DAO methods to find them.
On my current project, I decided to add a configuration option to allow me to run my datbase integration tests on my development Oracle database rather than my embedded HSQLDB test database - just for an extra sanity check. The tests that tried to persist() and then retrieve those new entities failed. Adding an entityManager.flush() method after the persist() invocations solved the issue.
The EntityManager.persist() operation is used to insert a new object into the database. persist does not directly insert the object into the database, it just registers it as new in the persistence context (transaction). When the transaction is committed, or if the persistence context is flushed, then the object will be inserted into the database. If the object uses a generated Id, the Id will normally be assigned to the object when persist is called, so persist can also be used to have an object’s Id assigned. The one exception is if IDENTITY sequencing is used, in this case the Id is only assigned on commit or flush because the database will only assign the Id on INSERT. If the object does not use a generated Id, you should normally assign its Id before calling persist.
Here’s how I wire up my entities’ primary key:
For my embedded HSQLDB database, the generation strategy is GenerationType.IDENTIY, which relies on the database to generate an autoincrementing primary key for that row. This requires an insert, so the persist() immediately inserts in HSQLDB.
Oracle, on the other hand, uses a cross-table GenerationType.SEQUENCE @Id generator, which doesn’t require an insert, but the following SELECT:
This select is called immediately on persist() so that the EntityManager has an ID to assign the entity. That entity will only be inserted after a flush(), which is called automatically on transaction commit.
Long story short: If you’re relying on your entity existing in the database after your call to persist(), but before the transaction commits, then call flush() first. Leave a comment justifying it, as manually calling flush is largely considered an anti-pattern akin to invoking the garbage collector. Delayed flush() calls give Hibernate the chance to perform more performant bulk updates.
When designing your classes, rather than following the path of the unreadable telescoping constructor, or leaving yourself open for bugs where the caller incorrectly passes a value into the wrong parameter because you have several of the same type, consider the following Builder pattern.
Having a private constructor will prevent anyone but the Person’s Builder from instantiating a Person. The setters in the Builder return the Builder, which allows method chaining, providing a DSL-like self-documenting interface. The Builder’s build() method is responsible for making sure that all properties are set before returning the Person.
Of course, this is a simple example with only two fields, so the alternative isn’t exactly error prone:
But, once you add a few more required fields, the following makes your code easier to follow, while still ensuring all required fields are set.
Apache Camel ™ is a versatile open-source integration framework based on known Enterprise Integration Patterns.
Camel empowers you to define routing and mediation rules in a variety of domain-specific languages, including a Java-based Fluent API, Spring or Blueprint XML Configuration files, and a Scala DSL. This means you get smart completion of routing rules in your IDE, whether in a Java, Scala or XML editor.
Apache Camel uses URIs to work directly with any kind of Transport or messaging model such as HTTP, ActiveMQ, JMS, JBI, SCA, MINA or CXF, as well as pluggable Components and Data Format options. Apache Camel is a small library with minimal dependencies for easy embedding in any Java application. Apache Camel lets you work with the same API regardless which kind of Transport is used - so learn the API once and you can interact with all the Components provided out-of-box.
Apache Camel provides support for Bean Binding and seamless integration with popular frameworks such as Spring, Blueprint and Guice. Camel also has extensive support for unit testing your routes.