Model development is one aspect of MVC that I do not have a lot of real world experience. Sure I am familiar with using an instance of a data model to work with Wicket. So developing the warehouse and book exchange data models was a great refresher.
Coding the persistence with respect to the Ebean ORM was a fairly painless process compared to using the Hibernate ORM. Both ORMs used the same Java persistence annotations, yet Hibernate and Ebean differed on model retrieval. Hibernate needs each model to be associated with an entity manager instance. Although associating each model with an entity manager may be such a trivial step when creating a new project, moving an existing project over to the Hibernate ORM means that I need to sacrifice time to manage each model’s association. On the other hand, Ebean does not have an entity manager. Just creating the model with the persistence annotations means the model is ready to use. No more Hibernate configurations!
The warehouse model example helped jump start the programming with the various relationship persistence tags. I found that writing the tests was helpful as it gave me a sterile environment to understand how the models interact with regards to the persistentce database.
My first rendition of the textbook exchange request and offer models referenced the foreign key for both the student and the book models. Basically I still thought in term of database relations rather than persistence relations. After creating the models in Java, it quickly became apparent that the foreign keys were unnecessary and that I had to replicate the warehouse stockitem relation from the warehouse example.
Textbook Exchange: ERROR executing DML bindLog error
[textbookexchange] $ test [info] Compiling 1 Java source to D:\workspace\textbookexchange\target\scala-2.1 0\test-classes... [error] Test models.ModelTest.testModel failed: ERROR executing DML bindLog er ror[Referential integrity constraint violation: "FK_REQUEST_STUDENT_3: PUBLIC.RE QUEST FOREIGN KEY(STUDENT_PRIMARY_KEY) REFERENCES PUBLIC.STUDENT(PRIMARY_KEY) (1 )"; SQL statement:\n insert into request (primary_key, price, condition, student _primary_key, book_primary_key) values (?,?,?,?,?) [23506-168]] [error] at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.execu te(DmlBeanPersister.java:97) [error] at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.inser t(DmlBeanPersister.java:57) [error] at com.avaje.ebeaninternal.server.persist.DefaultPersistExecute.exec uteInsertBean(DefaultPersistExecute.java:72) [error] at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeNow (PersistRequestBean.java:481) [error] at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeOrQ ueue(PersistRequestBean.java:511) [error] at com.avaje.ebeaninternal.server.persist.DefaultPersister.insert(De faultPersister.java:387) [error] at com.avaje.ebeaninternal.server.persist.DefaultPersister.saveEnhan ced(DefaultPersister.java:326) [error] at com.avaje.ebeaninternal.server.persist.DefaultPersister.saveRecur se(DefaultPersister.java:296) [error] at com.avaje.ebeaninternal.server.persist.DefaultPersister.save(Defa ultPersister.java:263) [error] at com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultSer ver.java:1610) [error] at com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultSer ver.java:1600) [error] at com.avaje.ebean.Ebean.save(Ebean.java:505) [error] at play.db.ebean.Model.save(Model.java:91) [error] at models.ModelTest.testModel(ModelTest.java:209) [error] ... [error] Caused by: org.h2.jdbc.JdbcSQLException: Referential integrity constrain t violation: "FK_REQUEST_STUDENT_3: PUBLIC.REQUEST FOREIGN KEY(STUDENT_PRIMARY_K EY) REFERENCES PUBLIC.STUDENT(PRIMARY_KEY) (1)"; SQL statement: [error] insert into request (primary_key, price, condition, student_primary_key, book_primary_key) values (?,?,?,?,?) [23506-168] [error] at org.h2.message.DbException.getJdbcSQLException(DbException.java:3 29) [error] at org.h2.message.DbException.get(DbException.java:169) [error] at org.h2.message.DbException.get(DbException.java:146) [error] at org.h2.constraint.ConstraintReferential.checkRowOwnTable(Constrai ntReferential.java:361) [error] at org.h2.constraint.ConstraintReferential.checkRow(ConstraintRefere ntial.java:303) [error] at org.h2.table.Table.fireConstraints(Table.java:871) [error] at org.h2.table.Table.fireAfterRow(Table.java:888) [error] at org.h2.command.dml.Insert.insertRows(Insert.java:126) [error] at org.h2.command.dml.Insert.update(Insert.java:84) [error] at org.h2.command.CommandContainer.update(CommandContainer.java:75) [error] at org.h2.command.Command.executeUpdate(Command.java:230) [error] at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPrepa redStatement.java:156) [error] at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedState ment.java:142) [error] at com.jolbox.bonecp.PreparedStatementHandle.executeUpdate(PreparedS tatementHandle.java:203) [error] at com.avaje.ebeaninternal.server.type.DataBind.executeUpdate(DataBi nd.java:55) [error] at com.avaje.ebeaninternal.server.persist.dml.InsertHandler.execute( InsertHandler.java:139) [error] at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.execu te(DmlBeanPersister.java:86) [error] ... 46 more [info] models.ModelTest [info] x models.ModelTest.testModel [info] [info] [info] Total for test models.ModelTest [info] Finished in 0.003 seconds [info] 1 tests, 1 failures, 0 errors [error] Failed: : Total 1, Failed 1, Errors 0, Passed 0, Skipped 0 [error] Failed tests: [error] models.ModelTest [error] (test:test) Tests unsuccessful [error] Total time: 8 s, completed Apr 10, 2013 9:59:10 PM [textbookexchange] $
In class we discussed a solution to this problem by adding getter and setter methods to each model’s attributes. I will update my code later if a more ideal solution does not appear.
Walk Through with Christopher Foo
There were a couple things I learned when Christopher walked me through his code and diagrams of his Warehouse and Textbook exchange models. We discussed the mapped-by persistence configuration since we both did not fully understand its usage.
Our textbook exchange model slightly differed where I assumed that a student to request is one to zero or many relation. Same went for the student to offer relation.
Beyond the foreign key error with the Ebean ORM, I found this experience deepen my understanding of the Persistence API. Previously, I used Hibernate ORM only to store the results from execute stored procedures, so annotations such as @ManyToOne were left unused as all the relations were done in the stored procedure. Even with a greater understanding of the persistence API, I still feel that persistence is not an ideal solution to interacting with a database.