Showing posts with label hibernate. Show all posts
Showing posts with label hibernate. Show all posts

Thursday, July 3, 2014

Vaadin 7 + Spring 3 + JPA project summary and lessons learned

This blogpost is a short summary of the Vaadin 7.0 project I did last year, including tools used, lessons learned and a bunch of screenshots to show the results.

Tools used

  • Spring 3.2 including annotation based configuration, Spring Task*Executor framework
  • JPA2 with Hibernate 4.2 + JPA modelgen, including Envers for auditing
  • JMS 2
  • Vaadin 7.0.1
  • JAXB 2.1
  • Spring WS 2.1
  • Shiro 1.2
  • JUnit 4.8
  • Mockito
  • Eclipse 3.7
  • SOAP + SoapUI
  • MySql 5.5 + H2
  • Tomcat 7
  • Jenkins
  • Fisheye/Crucible
  • Sonar
  • Subversion
  • Maven 3
  • Java 6

Lessons learned

  • Don't only trust SoapUI of being able to validate your WSDL. Also try to generate stubs with Axis2 and JAXWS generators. *AND* actually make sure you can make a call to the webservice, because on our project it did work perfectly fine in SoapUI, but not in Axis nor JAXWS. Example: soap fault in operation but not in porttype defined. It required the project to defining one or more xyz.jaxb files for JAX-WS  (using .episodes dit not work for us). Then use these in the wsimport etc. Related links: Compiling multiple WSDLs that share a common schema and Customizing Java Packages.
  • If sources not found of e.g junit-4.11 (junit.org is also giving a lot of 404s), then run mvn clean dependency:sources, that will download the sources too into the .m2 repo.
  • Try to keep the WSDL and XSD as semantic as possible, so use Strings instead of IDs for for example lookup /reference values like: started, finished. Makes the interface much more readable and understandable by just looking at it.
  • count(case ...) is NOT supported by Hibernate criteria API, when using it it gives: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: case near line 1, column 92 [...  Use sum(case) since that is supported.

    So instead of:

    cb.count(cb.selectCase().when(cb.equal(workOrder.get(WorkOrder_.priority), 1), workOrder.get(WorkOrder_.priority)).otherwise(0)),
    Use:

    cb.sum(cb.selectCase().when(cb.equal(workOrder.get(WorkOrder_.priority), 1), 1).otherwise(0)) 

    SQL equivalent:

    Instead of:

    COUNT(CASE WHEN priority = 1 THEN priority ELSE NULL END) AS prio1,

    Use:

    SUM(CASE WHEN priority = 1 THEN 1 ELSE 0 END) AS prio1,

    Links about this:

    https://forum.hibernate.org/viewtopic.php?f=1&t=992497
    https://forum.hibernate.org/viewtopic.php?p=2393060
    http://stackoverflow.com/questions/11011151/jpa-criteria-query-order-by-enum-values
    Sums replacement for count
    JPA 2.0 spec including 'case expressions' and this one and this one.
    http://stackoverflow.com/questions/775787/plsql-get-sum-for-each-day-of-week-and-total-sum-for-week-in-a-single-query
  • When trying to upgrade from Vaadin from version 7.0.1 to 7.0.4 by updating the version number in the pom.xml, a serial UID problem occurred when generating the widgetset for this new version:

    [INFO]  at com.google.gwt.dev.Compiler.main(Compiler.java:177)
    [INFO] Caused by: java.io.InvalidClassException: com.google.gwt.dev.jjs.ast.JMethod; local class incompatible: stream classdesc serialVersionUID = 5017484276333252513, local class serialVersionUID = 9103713597467037978

    Tried it then with 7.0.2, that one worked fine! 7.0.3 gave the same error. This post talks about maybe the GWT cache being the problem. So I deleted the directory (even though the timestamp on that directory was recent!) and that worked. In my case the directory to delete was:

    D:\workspace\xyz\frontend\app-web\src\main\webapp\VAADIN\gwt-unitCache 

The application

Below you can find a bunch of screenshots of the resulting application Planning Optimizer or ePOp.



The login screen, authentication via Shiro with a custom Realm that does a SOAP call to the backend:


The dashboard so the planner can immediately see the status + what needs attention first:

The Vaadin Charts 90 days look ahead graph shows the status for the coming 90 days. Clicking on a bar shows the orders at the bottom table for that day. A similar 12 weeks graph is available on another tab:



Different ways of looking at the status exist, for example these week-based graphs, the first one based on craft, the second one on priority:
Notice in the above graph the multiple y-axis: the bars are for the left y-axis, the lines for the right y-axis.

And other filters:




When clicking on a row in the bottom table, details for that order can be filled in:

Links (from a whitelist) and documents can be attached too (including drag 'n drop), and in the end a PDF can be generated with all the info (including the attachments + where the links are pointing to!) included:

Saturday, July 27, 2013

JPA @Version annotation: when is the version updated?


In JPA you can annotate a field of an entity with @Version to specify that property as its optimistic lock value.
But the above documentation does not say when the version number is validated and updated (increased).
The short answer is: at commit time!

I came across this because I was having trouble passing on the updated version number back to the caller, after a merge() operation.

The setup

Example and the solution

A client class (not in a transaction) invokes the method 

   /** 
    * Updates the order and returns the new version number for the order
    *
    * @param order the entity to update. Must be provided with the current version of the order.
    *             If not provided, StaleObjectStateException will be thrown
    */
   Date updateMe(Order orderWithNewValues);

on a service class, which is annotated with Spring @Service and Spring @Transactional

That method invokes 

   /** 
    * Similar java doc
    */
   Date updateMe(SomeEntity orderWithNewValues)

in a DAO which is annotated with Spring @Transactional(propagation = Propagation.MANDATORY) and @Repository.  The DAO searches for the entity to update using its name, sets the version number to the currently known version number, updates it and should return the new version number.

The class Order is annotated (amongst other things) with @Version as follows:

   @Version
   @Column(nullable = false)
   @Temporal(TemporalType.TIMESTAMP)
   private Date version;
   ...
   DateTime getVersion() {
       return version;
   }

The implementation of the DAO method implementing the update originally was:

   Order order = orderDao.findByName(name);
   if (order == null) {
       throw new IllegalArgumentException("No order with name '" + name + "' exists");
   }

   Order updatedOrderNotManaged = new Order(order);
   updatedOrderNotManaged.setVersion(orderWithNewValues.getVersion());
   updatedOrderNotManaged.setTotal(orderWithNewValues.getTotal());

   Order updatedOrderManaged = orderDao.merge(updatedOrderNotManaged);

   return updatedOrderManaged.getVersion();


Expecting that the last line (return updatedOrderManaged.getVersion()) would return the new version number, since the non-managed entity was now managed.

But it isn't! What seems to be the reason is that:
  • The JPA implementation (in this case Hibernate) can do some caching, deferring the actual database access to a later moment, causing the changes to not hit the database yet.
  • Not hitting the database also doesn't cause the @Version to be "triggered" (it seems).
  • So the version is still at its old value!
But after the service method had returned the (old) version to the client calling it (so the transaction was committed), in the database you can see the new increased timestamp in the version column.

The solution is to force the JPA implementation to flush() to the database, such that the @Version annotation gets triggered and thus the version gets updated.
Therefor the following was added, just before the "return"  statement: 


   orderDao.flush();

That did it, now return updatedOrderManaged.getVersion()) is returning the updated version number. Should the transaction commit fail later, then no harm is done since the whole transaction is rolled back and the client should get an exception or similar so it knows it should ignore the returned version number.


Wednesday, October 17, 2012

Lessons learned Seam 2.2 project

Quick post with some bullet points of lessons learned during my last (and first) Seam project:

  • Seam 2.2
  • Hibernate 3.3.1
  • JEE 5
  • EJB 3.0
  • JSF 1.2
  • Richfaces 3.3
  • JBoss 5.1
  • Drools 5
  • SQLServer 2008
  • MySql 5.x
  • TestNG
  • Hudson
Seam
- To have a navigation for a method with a parameter like exportSelected(String value): see Seam navigation based on a function with parameters
- If your Seam app keeps re-deploying (restarting) when using JBoss within Eclipse: delete all files that end with 'dia' in your WEB-INF dir. See: Seam keeps redeploying For example, I modified pages.xml, which apparently created a pagesdia (or similar) file... after removing that one, it worked fine again.

Hibernate
- To see which validator fails on a persist():


    try {
        entityManager.persist(verbinding);
    } catch (InvalidStateException e) {     
        for (InvalidValue invalidValue : e.getInvalidValues()) {         
            System.err.println("--------------> create(): exception Instance " +
               "of bean class: " + 
               invalidValue.getBeanClass().getSimpleName() +                  
               " has an invalid property: " + invalidValue.getPropertyName() +
               " with message: " + invalidValue.getMessage());     
        } 
	throw new RuntimeException(e);
    }




MySql
- To see data in better format in MySQL: show engine innodb status\G (so add the \G to a query)

Hibernate/JPA
- NamedQueries are loaded and parsed at startup time, so that's an advantage above em.createQuery() which are only parsed and evaluated at runtime. So with NamedQueries you get the errors sooner.

Drools
To solve this error in Drools decision table .XLS spreadsheet:


   [testng] DEBUG [test.service.drools.DroolsHandling] getKnowledgeBase: getting path info from settings service
   [testng] DEBUG [test.service.drools.DroolsHandling] getting test.service.drools.DroolsHandling ruletable file: HandlingModelTest.xls
   [testng] DEBUG [test.service.drools.DroolsHandling] getKnowledgeBase: Trying to open a File
   [testng] WARN  [jxl.read.biff.NameRecord] Cannot read name ranges for Excel_BuiltIn__FilterDatabase_1 - setting to empty
   [testng] WARN  [test.service.drools.DroolsHandling] There are errors in the decision table file
   [testng] WARN  [test.service.drools.DroolsHandling] Decision table error: message=[ERR 102] Line 9:16 mismatched input '"DroolsHandling6"' expecting ']' in rule "DroolsData_12" in pattern stringDataset
   [testng] WARN  [test.service.drools.DroolsHandling]     line: 9
   [testng] WARN  [test.service.drools.DroolsHandling] Decision table error: message=[ERR 102] Line 9:35 mismatched input '"Prefab"' expecting ']' in rule "DroolsData_12" in pattern stringDataset
   [testng] WARN  [test.service.drools.DroolsHandling]     line: 9
   [testng] WARN  [test.service.drools.DroolsHandling] Decision table error: message=[ERR 102] Line 22:16 mismatched input '"DroolsHandling6"' expecting ']' in rule "DroolsData_12" in rule "DroolsData_13" in pattern stringDataset
   [testng] WARN  [test.service.drools.DroolsHandling]     line: 22



Make sure your definition has all the cells merged that contain a condition! For example, check the red arrow pointing at the border of the cells between G9 and H9.
The last cell for the condition Prefab is not merged (i.e one cell) with all the other conditions. Here's now how it should be: see again the red arrow, there's no cell separation anymore, all condition columns are now merged into 1 cell.


- A space in a condition in a decision spreadsheet can cause a non-match! E.g GATE VALVE is not matched. Fixed it by always replacing a ' ' with an '_'.

Sunday, July 4, 2010

Lessons learned Wicket + Spring + Hibernate + Mod4J project

At a recent project we used the following tools & frameworks:


Below are a couple of lessons learned which I remembered to write down:

Wicket
  • In a ModalWindow you'd probably want to use a AjaxSubmitLink, not a SubmitLink, if you want to use modalWindow.setWindowClosedCallback(). See here for explanation.

  • ajaxrequesttarget.addComponent: addComponent name might be a bit confusing for beginners. It means "add the component to the list of components be re-rendered/refreshed".

  • An AjaxSubmitLink doesn't update the model when setDefaultFormProcessing() is set to false. Not totally illogical, but you still might run it to it when you don't expect it.

  • Here are tips to validate related fields. (In the original the example code is missing.)

  • AjaxSubmitLink: if you get a "Component-targetted feedback message was left unrendered. This could be because you are missing a FeedbackPanel on the page" warning in your Tomcat server console, it seems you have to tell in the onError() of the AjaxSubmitLink which feedback panel(s) you want to have updated.
    You get the warning even when you have feedback panels higher up in the tree of the (Base)Page. An example to update those panels could be:

    Component infoFeedback = getPage().get("infoPanel");
    target.addComponent(infoFeedback);
    Component warnFeedback = getPage().get("warningPanel");
    target.addComponent(warnFeedback);
    Component errorFeedback = getPage().get("errorPanel");
    target.addComponent(errorFeedback);

    This solution was inspired by these posts: post1, post2, post3, post4.

  • To show/hide any HTML markup block dynamically, just wrap it with a WebMarkupContainer. In the code create that wrapper and make it visible or not depending on your requirements:

    boolean makeVisible = false;
    WebMarkupContainer blockContainer = new WebMarkupContainer("blockWrapper");
    blockContainer.setVisible(makeVisible);
    add(blockContainer);


  • Sometimes you might get a popup when using a ModalWinow that says "Reloading this page will cause modal window to disappear" when you don't expect it. Check the logs/console, you might just got an exception in your app (after which Wicket tries to redirect to the error page, which causes the popup to show; at least that's my reasoning).

JUnit
  • If JUnit can't find the Spring context.xml in the resources directory, then you have to add the resources dir to your Build path

Mod4J
  • Does not really support LazyLoading so not very efficient for large "graphs" of data/dependencies. In those cases you could decide to skip the DTO layer and directly access the domain model.

  • The Maven plugin IAM in Eclipse can be turned off for the Mod4J models project in Eclipse, otherwise it runs twice: once by Mod4J features, once by Maven (plugin).

Sunday, April 25, 2010

Best of this Week Summary 19 April - 25 April 2010

  • An introduction to Gizzard, an open sourced sharding framework (store data across multiple computers instead of on just one) which is used by Twitter.

  • A hands-on tutorial of creating a Spring application that uses Hibernate as JPA provider and JTA for transaction demarcation. A simple Order Processing Message Driven Bean is implemented that showcases this integration. It is deployed on a WebLogic 10.3 server.

  • Last week Jira from the Apache Foundation was compromised. Here's a description of how the hackers gained access via XSS.

Sunday, November 22, 2009

Best of this Week Summary 16 November - 22 November 2009

Sunday, September 20, 2009

Best of this Week Summary 14 September - 20 September 2009

  • Scala is slowly getting some more and more traction lately. Is it a potential long term replacement for Java?
    Interview with Scala creator Martin Odersky where he tells its history, future and why it's so interesting (like combining OO- and functional techniques).

  • Six valid "takeaways on what most REST adopters can and should do to get the most from their use of this increasingly popular architectural style" summarised by Dion Hinchcliffe.

  • Article that describes using Benerator, which is a data generator tool that can be used to feed database with pseudo-random test data.

  • Tip that shows you how to implement composite keys with JPA and Hibernate. Check also the comments here.

Sunday, May 24, 2009

Best of this Week Summary 18 May - 24 May 2009

Sunday, April 5, 2009

Best of this Week Summary 24 March - 05 April 2009

  • How can you make sure your site can handle peak-loads? This article lists the possibilities:

    • Over-provisioning (estimating what the peak will be).

    • Under-provisioning.

    • Right-sizing: estimate for a short period in time, then scale up or down: flexible scaling and auto-scaling.

    How this can be achieved? Add a middleware virtualisation layer that helps the application take advantage of these new dynamically added resources. The article also describes in detail how to add auto-scaling to your existing application, including a description how to try it out on GigaSpaces XAP which uses EC2.

  • Quite amazing, Salesforce.com runs on only about 1000 servers (and that's mirrored, so only really about 500 servers). Salesforce has more than 55K enterprise customers, 1.5M individual subscribers, 30M lines of third-party code and hundreds of TBs of data.

  • Here's a list of criteria when selecting a SOA testing tool.

  • A nice introduction to Hibernate's second-level cache.

  • Five tips for successfully deploying Maven. Including a bunch of pros and cons in the comments.

  • On a keep-an-eye-on-this-innovation side note, Digg introduced a interesting (new?) way of a URL shortener like TinyURL, and at the same time attract traffic. Just prefix any URL with http://digg.com/, and voila, a shortened URL appears including a Digg toolbar. Below I entered http://digg.com/http://ttlnews.blogspot.com/ in the address bar:


Sunday, March 1, 2009

Best of this Week Summary 17 February - 01 March 2009

  • A relatively new type of mashups are so called clipping mashups. Instead of building a mashup against some official API, a clipping mashup just parses the final content in the presentation, thus including CSS, Javascript etc. Links can be rewritten, new elements injected. The presentation doesn't have to follow for example portal JSR-168 standards.
    An example use case would be that you could use it to (temporarily) fix a bug in a system (not necessarily owned by you) until the official next release comes out.

  • Eight architectural styles described. Handy overview including which one could be when appropriate.

  • Summary of migration project from JDBC to Hibernate. Valid comment at the bottom is that iBatis might be a better solution when you have to work from an existing schema.

  • Additional tips and articles for the Wicket in Action book. For example this article on how to do a partial Ajax repaint of newly created repeater items (e.g adding 1 row dynamically to a table or list with a "+" button). This in contrast to rendering all rows in a table when repainting the WebMarkupContainer as in the example described here.

  • Nice step-by-step introduction to asynchronous processing in Java 5 using Futures, ExecutorServices, CompletionService, Callback interfaces and ThreadPools. Here's part 2 where it's being used in combination with Javascript to improve the user experience.

Saturday, September 27, 2008

Best of this Week Summary 22 September - 28 September 2008

Saturday, September 20, 2008

Best of this Week Summary 15 September - 21 September 2008

  • It seems the SOA world is finally starting to take the Web-Oriented Architecture seriously.

  • Summary of a recent whitepaper from IBM Global Services describing five high level best practices for successful deployment of an SOA. 120 IT Architects, developers, IT Specialists and project managers evaluated nearly 100 case studies, with 750 lessons learned and 650 best practices.

  • SpringSource announced a maintenance policy for SpringSource Enterprise. Definitely check Rod Johnson's clarification comment in this thread on The ServerSide. Important to verify when you're using Spring in your company.

  • Elaborate introduction to persistence, ORM and JPA, and a comprison of two open source persistence frameworks: iBATIS and Hibernate. Notable points: iBATIS encourages the direct use of SQL queries; it enables the object model and the data model to be independent of eachother via its data mapper (compared to a metadata mapper framework like Hibernate). Note that fully ORM tools generate SQL, where iBATIS uses SQL directly. A nice quick overview of the Hibernate architecture is described; the diagram is shown below:


    Recommendations from the article:
    1. Use iBATIS when you need full control of the SQL
    2. Don't use iBATIS when you are in full control of both the application (with its domain model) and the data model.
    3. Don't use iBATIS when the database is non-relational
    4. Use Hibernate to leverage end-to-end OR mapping
    5. A potential reason to use it could be that it is more easy to use for object-oriented programmers who are less familiar with SQL
    6. Use JPA when you need a standards-based persistence solution


    My own recommendations:
    1. With Hibernate it might be harder to tune the queries because they are generated by Hibernate. You can't really "just handover" the queries to the DBA. The DBA will have to monitor the database for bad queries.
    2. Hibernate gets quite complex when you have to map more complex associations (like a unidirectional many-to-many association with custom columns added to the link-table). I've never used iBatis so can't tell how hard it is for that framework.
    3. When trying to only use JPA defined elements, you'll find that JPA's possibilities are quite limited (e.g. caching is not well defined in JPA), and that you quickly will start to use (ORM-tool) implementation specific features. A good way to implement this, is to specify the full package path when using implementation specific annotations. That way you can see where you deviate from the JPA standard.

Saturday, September 6, 2008

Best of this Week Summary 1 September - 7 September 2008

Sunday, August 31, 2008

Best of this Week Summary 25 August - 31 August 2008

  • Water & Stone PDF with an analysis of 19 open source content management systems. WordPress, Joomla! and Drupal come out best.

  • Recently released Keyczar is an open source cryptographic toolkit designed to make it easier and safer for developers to use cryptography in their applications. It supports authentication and encryption with both symmetric and asymmetric keys. Keyczar is designed to be open, extensible, and cross-platform compatible. It is not intended to replace existing cryptographic libraries like OpenSSL, PyCrypto, or the Java JCE, and in fact is built on these libraries.

  • How to add custom columns to the association using Hibernate 3.2.5 (and Spring 2.5). Quite unbelievable that this has to be so complex. It's quite simple with a @ManyToMany or similar annotation if you don't want an extra column in the association (link table). But I think it's quite normal that you like to add more columns, for example a timestamp of when the record was created.

  • Great summary of Eric Meyer's talk at An Event Apart San Francisco 2008 about 9 CSS frameworks: 960, Blueprint, Content With Style, That Standards Guy, YAML, YUI, Elements, Tripoli and WYMStyle. In short: CSS templates are a good starting point, but to make the design unique you will very likely have to modify the templates.