Browse files

Adding loose files

  • Loading branch information...
1 parent d8b27b8 commit 49843a5351551e7c05ed6c752d3b8be6a94d0288 @credmp committed Mar 6, 2013
View
1 _includes/custom-js.js
@@ -1,6 +1,7 @@
<script src="http://code.jquery.com/jquery-1.7.2.min.js" type="text/javascript" ></script>
<script src="/assets/js/jquery.cookie.js" type="text/javascript" ></script>
<script src="/assets/js/jquery.cookiecuttr.js" type="text/javascript" ></script>
+<script src="/assets/js/jquery.toc.min.js" type="text/javascript" ></script>
<script type="text/javascript">
$(function(){
View
1 _includes/toc
@@ -0,0 +1 @@
+<div id="toc"></div>
View
3 _includes/toc_call
@@ -0,0 +1,3 @@
+<script type="text/javascript">
+$('#toc').toc();
+</script>
View
501 _posts/2013-01-13-java-adding-persistence.md
@@ -0,0 +1,501 @@
+---
+tags: [Java]
+title: "Java; adding persistence"
+series: developing a Java application
+image: /assets/post_images/java_from_nothing/2.persistence.png
+layout: post
+---
+{% include JB/setup %}
+{% include series.html %}
+
+
+# Lets store some stuff
+
+In the [first article](/2013/01/Java-starting-at-nothing) we started
+our project to create a simple movie database. We will be using a lot
+of cool stuff along the way and in this article we will explore
+persistence.
+
+My aim was to keep it simple, but persistence is anything but simple.
+Sure, you can just create a JDBC connection and do stuff, but that
+doesn't give you the tools to use the rich and powerful world that I
+want to show you.
+
+So, if the first article was a beginners introduction to a project,
+then this will be a step up into some of the complexities of
+persistence.
+
+At a high level we will be using only a few things:
+
+ - A postgres database
+ - If you are on a Mac I highly recommend [PostgresApp](http://postgresapp.com)
+ - Hibernate as an Object-Relational Mapping tool
+ - Spring to connect everything and its testing support
+ - DBUnit to do some testing
+
+One can write books on each of these subjects and people of course
+have. I will not go into full depth on each, but I will get you up and
+running with them.
+
+The sources for this article are available on [Github](https://github.com/credmp/java-from-nothing/tree/02_adding_persistence).
+
+## Pull in some dependencies
+
+The first thing we will do is enhance our **pom.xml** file to include
+the dependencies we require for our project. Keeping with good form we
+will first introduce the properties and after that we will update the
+dependencies.
+
+{% highlight xml %}
+ <org.dbunit.version>2.4.8</org.dbunit.version>
+ <logback-version>1.0.7</logback-version>
+ <hibernate-version>4.1.8.Final</hibernate-version>
+ <cglib.version>2.2.2</cglib.version>
+ <commons-dbcp.version>1.4</commons-dbcp.version>
+ <postgresql.version>9.1-901.jdbc4</postgresql.version>
+{% endhighlight %}
+
+Following we will add each dependency to the **dependencies** list. In
+total we will add 12 new dependencies. To save you some reading here
+you can find the full [pom.xml on Github](https://github.com/credmp/java-from-nothing/blob/02_adding_persistence/pom.xml)
+
+## Logging with logback
+
+You might wander about the *logback* dependency. I use logback for
+logging, it is a quite powerful framework which makes dealing with
+logging quite easy. I introduce it to the project now as the
+**Hibernate** and **Spring** output can be quite overwhelming.
+
+The configuration for logback can be found in **src/test/resources/logback.xml**
+and is as follows:
+
+{% highlight xml %}
+<?xml version='1.0' encoding='UTF-8'?>
+<configuration>
+ <appender name='CONSOLE' class='ch.qos.logback.core.ConsoleAppender'>
+ <encoder>
+ <pattern>%d %5p | %t | %-55logger{55} %L | %m %n</pattern>
+ </encoder>
+ </appender>
+
+ <logger name='org.springframework'>
+ <level value='INFO' />
+ </logger>
+ <logger name='org.hibernate'>
+ <level value='INFO' />
+ </logger>
+ <logger name='org.dbunit'>
+ <level value='INFO' />
+ </logger>
+
+ <root>
+ <level value='DEBUG' />
+ <appender-ref ref='CONSOLE' />
+ </root>
+</configuration>
+{% endhighlight %}
+
+Basically this file configures all the logging we need. It sets up a
+[PatternLayout](http://logback.qos.ch/manual/layouts.html) so that we
+can get some nicely organized data on the screen.
+
+Next we will reduced the logging from **Spring**, **Hibernate** and
+**DBUnit** by setting their level to *INFO*. This means we will only
+get information at the *INFO* level or more severe.
+
+The rest of the code, including our own will use the level set in the
+*root* element, in this case *DEBUG*.
+
+# Annotations all over the place
+
+In the good old days we would now start writing code that maps objects
+to databases and create a million and one data access objects
+(**DAO**). At this point in our project we will not do this. We will
+use the **javax.persistence** [annotations](http://docs.oracle.com/javaee/5/api/javax/persistence/package-summary.html)
+
+We will be using 6 annotations for our project, namely @Entity,
+@Column, @Id, @GeneratedValue, @Version and @OneToOne.
+
+## @Entity
+
+In order for the system to know that it should at least be able to
+persist an object its class needs to be annotation with @Entity.
+
+A class annotated with @Entity will be transferred to the database as
+a **table**. So our Actor class will become an Actor table in our database.
+
+[JavaDoc](http://docs.oracle.com/javaee/5/api/javax/persistence/Entity.html)
+
+## @Column
+
+(Almost) every attribute that you wish to store in the database as a
+column has to be annotated with @Column.
+
+This will create a column with the name of the property of which the
+values are **non-unique** and its value is **nullable**. The column
+will be included in **insert** and **update** statements and its **type**
+will be deduced from the inferred type.
+
+For a string the default **length** of 255 is used and for decimal
+value the **precision** and **scale** are set to 0.
+
+For our version field, discussed later, we will need to set a default
+value. This is not possible by using annotations alone so we need to
+provide the SQL based definition of the column in **columnDefinition**.
+
+[JavaDoc](http://docs.oracle.com/javaee/5/api/javax/persistence/Column.html)
+
+## @Id
+
+The @Id annotation indicates that the property is the primary key for
+the table.
+
+The magic for this column happens in @GeneratedValue.
+
+[JavaDoc](http://docs.oracle.com/javaee/5/api/javax/persistence/Id.html)
+
+## @GeneratedValue
+
+The @GeneratedValue tells the primary key how it is to be generated.
+By passing a **generator** and a **strategy** the database can create
+its internal objects accordingly.
+
+Not all databases support all the possible values. There is a nice
+overview on
+[wikibooks](http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing)
+on the subject.
+
+In our application we will be using **GenerationType.IDENTITY** as
+this is portable between MySQL and PostgreSQL.
+
+[JavaDoc](http://docs.oracle.com/javaee/5/api/javax/persistence/GeneratedValue.html)
+
+## @Version
+
+The @Version annotation allows us to use **optimistic locking**. This
+technique prevents a lot of locks, and thus waiting code, on the
+database by introducing a field, **version**, which will change value
+with each update.
+
+When our code performs an update it will check if the **version**
+field changed value in the meantime. If it changed then our statement
+will fail and we will need to deal with the error accordingly.
+
+The subject of optimistic locking is thoroughly explained on [wikipedia](http://en.wikipedia.org/wiki/Optimistic_concurrency_control).
+
+[JavaDoc](http://docs.oracle.com/javaee/5/api/javax/persistence/Version.html)
+
+## @OneToOne
+
+As the name suggests the @OneToOne annotation maps one object to
+another. For instance; a piece of **Trivia** belongs to an **Actor**.
+
+The other way around, @ManyToOne and @OneToMany, also exists, but we
+will not touch them, yet.
+
+The @OneToOne annotation is not **Lazy**, this means that when we
+retrieve a **Trivia** object it will also retrieve the **Actor**. This
+behaviour can be changed, however for these mappings it doesn't make sense.
+
+[JavaDoc](http://docs.oracle.com/javaee/5/api/javax/persistence/OneToOne.html)
+
+## The annotated classes
+
+Following the explanation from about we will annotate our classes. You
+can see the code for all the classes on
+[Github](https://github.com/credmp/java-from-nothing/tree/02_adding_persistence/src/main/java/org/credmp/fromnothing/model).
+As an example of the simple annotations, lets take a look at the Actor class.
+
+{% highlight java %}
+@Entity
+public class Actor {
+ @Id
+ @GeneratedValue(strategy=GenerationType.IDENTITY)
+ private long id;
+ @Column(nullable=false)
+ private String firstName;
+ @Column(nullable=true)
+ private String lastName;
+ @Column(nullable=true)
+ private String nickName;
+ @Column(nullable=true)
+ private Date birthDate;
+ @Column(nullable=true)
+ private Date dateOfDeath;
+ @Column(nullable=true)
+ private String credit;
+ @Version
+ @Column(columnDefinition="bigint not null default 0")
+ private long version;
+{% endhighlight %}
+
+And if we take a look at the **Trivia** class we see almost the same
+code, except for the @OneToOne annotation.
+
+{% highlight java %}
+@Entity
+public class Trivia {
+ @Id
+ @GeneratedValue(strategy=GenerationType.IDENTITY)
+ private long id;
+ @OneToOne
+ private Actor actor;
+ @Column
+ private String text;
+ @Version
+ @Column(columnDefinition="bigint not null default 0")
+ private long version;
+{% endhighlight %}
+
+# Testing
+
+Phew, we annotated all our classes... now what? Well, we will write
+some testcode to use these annotations. We will create a database,
+fill it with some data and then perform several tests on it.
+
+In regards of testing this is call **Integration Testing**. The upside
+of it is that you get a good feel for the accuracy of your code on a
+grand scale, the downside is that it can take quite some time to run
+the test.
+
+As a result we will split our testing cycle between **Unit Tests** and
+**Integration Tests**. Maven will gladly help us here.
+
+## Create a database
+
+But first things first, lets create a database to use for testing. As
+we are using **Postgres** for this application I highly recommend to
+use [pgAdmin3](http://www.pgadmin.org) for the job.
+
+First create a new **Login Role** with the username **yourusername**
+and the password **yourpassword**. You can pick anything you like, as
+long as your remember it.
+
+Then, under **localhost**, create a new database called
+**fromnothing_test** and assign ownership to **yourusername**.
+
+It is important to use a seperate database for testing as we will
+destroy the entire thing every chance we get to ensure our code is
+working correctly on the latest schema generated by **Hibernate**.
+
+## DBUnit and extensions
+
+I will continue to build up the information you need in order to fully
+understand the integration test we will be creating at the end. The
+next piece of information we need is [DBUnit](http://www.dbunit.org).
+
+DBUnit is a tool which allows you to populate your database with a set
+of known data on which you can create tests. This allows you to have
+predictable outcomes every single time.
+
+There are 2 annotations in the project
+[CleanInsertTestExecutionListener](https://github.com/credmp/java-from-nothing/blob/02_adding_persistence/src/test/java/org/credmp/dbunit/CleanInsertTestExecutionListener.java)
+and
+[DataSetLocation](https://github.com/credmp/java-from-nothing/blob/02_adding_persistence/src/test/java/org/credmp/dbunit/DataSetLocation.java).
+
+The first, the CleanInsertTestExecutionListener, ensures that before
+every testmethod runs the database is brought back to a known state.
+In our case it will clean out all the data and reimport our basic set
+of data.
+
+It knows where to get our data from the DataSetLocation. We will set
+this location to **die-hard-set.xml** which will be sought for in the
+classpath. The XML file itself is available on [Github](https://github.com/credmp/java-from-nothing/blob/02_adding_persistence/src/test/resources/die-hard-set.xml).
+
+As we are creating tests in Maven there is a location where we can
+store files that are needed on the classpath. This location is
+**src/test/resources**.
+
+## Telling hibernate what to do
+
+Next we will instruct hibernate what to do for us. This is actually a
+two-fold process. First we will create an XML file call
+**hibernate.cfg.xml** which is located in the resources directory and
+thus available on the classpath.
+
+This file lists all the classes that we want our hibernate system to
+look at for annotations.
+
+{% highlight xml %}
+<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+"-//Hibernate/Hibernate Configuration DTD//EN"
+"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <session-factory>
+ <mapping class="org.credmp.fromnothing.model.Actor" />
+ <mapping class="org.credmp.fromnothing.model.Movie" />
+ <mapping class="org.credmp.fromnothing.model.MovieCredits" />
+ <mapping class="org.credmp.fromnothing.model.Trivia" />
+ <mapping class="org.credmp.fromnothing.model.Quote" />
+ <mapping class="org.credmp.fromnothing.model.Biography" />
+ </session-factory>
+
+</hibernate-configuration>
+{% endhighlight %}
+
+The second part of the configuration will happen in **Spring**.
+
+## Testing with Spring
+
+**Spring** is a key component in our application. Its **Inversion Of
+Control**, IOC, mechanism allows us to define the existance of our objects
+and the IOC mechanism will connect all the objects.
+
+This prevents us from having the hardcode the relationship of objects.
+
+When we look at the class definition for our test you will see all the
+annotations coming together and a few new ones as well.
+
+{% highlight java %}
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+@DataSetLocation("die-hard-set.xml")
+@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
+ CleanInsertTestExecutionListener.class,
+ TransactionalTestExecutionListener.class})
+@TransactionConfiguration(transactionManager="transactionManager",
+ defaultRollback = true)
+@Transactional
+public class PersistenceTestIT {
+{% endhighlight %}
+
+The @RunWith annotation tells **JUnit** to use the SpringJUnit2ClassRunner
+class, this allows for several **Spring** centric features to be used.
+
+The @ContextConfiguration without any parameters creates an IOC
+container and expects to find an XML file on the classpath at the same
+location as the class with a name derived from the classname itself.
+
+In our case it expects to find
+**org/credmp/fromnothing/PersistenceTestIT-context.xml** on the
+classpath, so we create this file in the resources directory with a
+few subdirectories for org, credmp and fromnothing.
+
+The other annotations are related to the *Transactional* support of
+**Spring**. Basically each test method becomes a transaction in the
+database and all actions executed in them will be rolled back.
+
+The entire XML file is quite large, so it is best viewed on
+[Github](https://github.com/credmp/java-from-nothing/blob/02_adding_persistence/src/test/resources/org/credmp/fromnothing/PersistenceTestIT-context.xml).
+Lets take a look at the most interesting parts:
+
+Configure the system to read the JDBC connection properties from [jdbc.properties](https://github.com/credmp/java-from-nothing/blob/02_adding_persistence/src/test/resources/jdbc.properties).
+
+{% highlight xml %}
+<bean id="propertyConfigurer"
+ class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
+ p:location="jdbc.properties" />
+{% endhighlight %}
+
+For the **Spring** and **Hibernate** integration we will need a
+datasource, for which I choose to use the implementation form
+**commons-dbcp**.
+
+We wil configure **Spring**'s implementation of a **SessionFactory**
+for **Hibernate**. This object connects the datasource,
+hibernate.cfg.xml and the second stage of hibernate configuration.
+
+Here we tell hibernate which dialect to use, to show us the SQL it
+uses and to recreate the schema each time we run the integration
+tests.
+
+And finally we setup a **Transaction Manager** to deal with database
+transactions.
+
+{% highlight xml %}
+<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
+ p:driverClassName="${jdbc.driverClassName}"
+ p:url="${jdbc.databaseurl}"
+ p:username="${jdbc.username}"
+ p:password="${jdbc.password}" />
+
+<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
+ <property name="dataSource" ref="dataSource" />
+ <property name="configLocation">
+ <value>classpath:hibernate.cfg.xml</value>
+ </property>
+ <property name="hibernateProperties">
+ <props>
+ <prop key="hibernate.dialect">${jdbc.dialect}</prop>
+ <prop key="hibernate.show_sql">true</prop>
+ <prop key="hibernate.hbm2ddl.auto">create</prop>
+ </props>
+ </property>
+</bean>
+
+<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
+ <property name="sessionFactory" ref="sessionFactory"/>
+</bean>
+{% endhighlight %}
+
+In the integration test itself we have 1 object which is actually
+directly injected from the IOC; the sessionFactory.
+
+{% highlight java %}
+@Autowired
+private SessionFactory sessionFactory;
+{% endhighlight %}
+
+## Maven failsafe
+
+{% highlight xml %}
+<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <version>2.12.4</version>
+ <executions>
+ <execution>
+ <id>integration-test</id>
+ <goals>
+ <goal>integration-test</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>verify</id>
+ <goals>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+</plugin>
+{% endhighlight %}
+
+## The integration test
+
+{% highlight java %}
+getSession()
+.createSQLQuery("SELECT setval('actor_id_seq', (SELECT MAX(id) FROM actor))")
+.list();
+{% endhighlight %}
+
+Saving an actor
+
+{% highlight java %}
+Actor actor = new Actor();
+actor.setFirstName("Arnold");
+actor.setLastName("Schwarzenegger");
+actor.setNickName("Arnie");
+Date date1 = new SimpleDateFormat("MM/dd/yy").parse("06/30/47");
+actor.setBirthDate(date1);
+
+getSession().save(actor);
+{% endhighlight %}
+
+{% highlight java %}
+Query query = getSession().createQuery("from Actor where nickname=:nickname");
+query.setParameter("nickname", "Arnie");
+
+Actor arnie = (Actor) query.uniqueResult();
+{% endhighlight %}
+
+{% highlight java %}
+getSession().delete(actor);
+Actor arnie3 = (Actor) query.uniqueResult();
+assertEquals("Arnie should no longer exist!", null, arnie3);
+{% endhighlight %}
+
+
+
View
27 _posts/2013-02-23-Project-Euler-Problem-1.md
@@ -0,0 +1,27 @@
+---
+tags: [Erlang, Project Euler]
+title: "Project Euler Problem 1"
+image: /assets/post_images/project-euler.png
+image_credit: Project Euler
+layout: post
+---
+
+Below my solution to the 1st problem of [Project Euler](http://projecteuler.net/problem=1).
+
+Problem:
+
+If we list all the natural numbers below 10 that are multiples of 3
+or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
+
+Find the sum of all the multiples of 3 or 5 below 1000.
+
+Solution:
+
+{% highlight erlang %}
+-module(problem1).
+-export([main/1]).
+
+main(Number) ->
+ lists:sum(lists:filter(fun(X) -> (X rem 3 == 0) or (X rem 5 == 0) end,
+ lists:seq(1,Number))).
+{% endhighlight %}
View
40 assets/css/toc.css
@@ -0,0 +1,40 @@
+#toc {
+ top: 0px;
+ left: 0px;
+ height: 100%;
+ position: fixed;
+ background: #333;
+ box-shadow: inset -5px 0 5px 0px #000;
+ width: 150px;
+ padding-top: 20px;
+ color: #fff;
+}
+
+#toc ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+#toc li {
+ padding: 5px 10px;
+}
+
+#toc a {
+ color: #fff;
+ text-decoration: none;
+ display: block;
+}
+
+#toc .toc-h2 {
+ padding-left: 10px;
+}
+
+#toc .toc-h3 {
+ padding-left: 20px;
+}
+
+#toc .toc-active {
+ background: #336699;
+ box-shadow: inset -5px 0px 10px -5px #000;
+}
View
8 assets/js/jquery.toc.min.js
@@ -0,0 +1,8 @@
+/*!
+ * jquery.toc.js - A jQuery plugin that will automatically generate a table of contents.
+ * v0.1.1
+ * https://github.com/jgallen23/toc
+ * copyright JGA 2012
+ * MIT License
+ */
+!function(e){e.fn.toc=function(t){var n=this,r=e.extend({},jQuery.fn.toc.defaults,t),i=e(r.container),s=e(r.selectors,i),o=[],u=r.prefix+"-active",a=function(t){for(var n=0,r=arguments.length;n<r;n++){var i=arguments[n],s=e(i);if(s.scrollTop()>0)return s;s.scrollTop(1);var o=s.scrollTop()>0;s.scrollTop(0);if(o)return s}return[]},f=a(r.container,"body","html"),l=function(t){if(r.smoothScrolling){t.preventDefault();var i=e(t.target).attr("href"),s=e(i);f.animate({scrollTop:s.offset().top},400,"swing",function(){location.hash=i})}e("li",n).removeClass(u),e(t.target).parent().addClass(u)},c,h=function(t){c&&clearTimeout(c),c=setTimeout(function(){var t=e(window).scrollTop(),i;for(var s=0,a=o.length;s<a;s++)if(o[s]>=t){e("li",n).removeClass(u),i=e("li:eq("+(s-1)+")",n).addClass(u),r.onHighlight(i);break}},50)};return r.highlightOnScroll&&(e(window).bind("scroll",h),h()),this.each(function(){var t=e(this),n=e("<ul/>");s.each(function(i,s){var u=e(s);o.push(u.offset().top-r.highlightOffset);var a=e("<span/>").attr("id",r.anchorName(i,s,r.prefix)).insertBefore(u),f=e("<a/>").text(r.headerText(i,s,u)).attr("href","#"+r.anchorName(i,s,r.prefix)).bind("click",function(n){l(n),t.trigger("selected",e(this).attr("href"))}),c=e("<li/>").addClass(r.itemClass(i,s,u,r.prefix)).append(f);n.append(c)}),t.html(n)})},jQuery.fn.toc.defaults={container:"body",selectors:"h1,h2,h3",smoothScrolling:!0,prefix:"toc",onHighlight:function(){},highlightOnScroll:!0,highlightOffset:100,anchorName:function(e,t,n){return n+e},headerText:function(e,t,n){return n.text()},itemClass:function(e,t,n,r){return r+"-"+n[0].tagName.toLowerCase()}}}(jQuery)
View
BIN assets/post_images/java_from_nothing/2.persistence.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN assets/post_images/project-euler.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
9 git.md
@@ -0,0 +1,9 @@
+# Git
+
+
+ git pull --recurse-submodules
+
+To checkout proper commits in your submodules you should update them
+after pulling using
+
+ git submodule update --recursive
View
15 maven.md
@@ -0,0 +1,15 @@
+---
+layout: page
+title: Links
+---
+
+# Maven
+
+This page contains everything I know about maven
+
+
+[Maven Ex Book](http://www.sonatype.com/books/mvnex-book/reference/customizing-sect-custom-exec.html)
+
+## Getting help
+
+ mvn help:describe -Dplugin=exec -Dfull

0 comments on commit 49843a5

Please sign in to comment.