Minborg

Minborg
Minborg

Friday, December 9, 2016

Day 9, Java Holiday Calendar 2016, Event Sourcing

9. Event Sourcing



Today's tips is about Event Sourcing which is a relatively new way of designing database applications. Instead of seeing the database as a representation of the most current state, we would see it as a system of record for all transactions that ever took place in our applications. 

So, instead of saying "find person 3 and replace that persons salary with whatever it is right now plus $100" we would say "person 3's salary increased by $100". Note the subtile but important distinction. 

If we use the first scheme, then we would know the current salary but not what it was before, by how much it increased and when it increased. The latter scheme however, allows us to replay all transactions so that we can re-produce all states the application ever had. Great when we are hunting bugs. 

Another important property of event sourcing is that we do not need the (expensive) absolute consistency of the underlying database. Instead, we only need to make sure that the order of the events remain consistent over time.

How do we keep track of the most recent value in an event sourcing system when it is changing all the time? Well, we could implement something called a Materialized View that holds the most current state. So, if we have an event table called employee_events then we could have a Java class EmployeeView that continuously will replay the events in the employees_event table and distiller the fold of all events so that we would actually know what salary person 3 has at the moment.

When the number of events increases, it would be more and more expensive to fast forward all the events, for example when the application restarts. To combat this drawback, the EmployeeView could create periodic snapshots from which it can be restarted. 

Event Sourcing is particularly interesting for applications with a micro service architecture.

Read more about Event Sourcing on Emil Forslund's blog here and on Event Sourcing and Micro Services on eventuate.io here.

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.




Thursday, December 8, 2016

Day 8, Java Holiday Calendar 2016, Use Traits

8. Use Traits in Java


Today's tips is about defining your classes and interfaces using Traits. This allows you to simplify your code and reuse components efficiently without creating unnecessary coupling or inheritance between your classes.

Suppose we have two district interfaces Table and Column that both have names, then we would introduce a name trait HasName that both interfaces extends. A Table and Column can also have an alias so because of that, we would introduce the trait HasAlias:

    interface Table extends HasName, HasAlias, HasOtherTableProperties {}
    interface Column extends HasName, HasAlias, HasOtherColumnProperties {}
    
    interface HasName {
        void setName(String name);
        String getName();
    }
    
    interface HasAlias {
        void setAlias(String alias);
        String getAlias();
    }
    
    public <T extends HasName & HasAlias> void printNameAndAlias(T item) {
        System.out.format("Name=%2, Alias=%s%n", item.getName(), item.getAlias());
    }

Notice in the last method, printNameAndAlias(), how we define a dynamic compound type T that must be both HasName and HasAlias but does not care about other traits or defined methods. The nice thing now is that once we define a Schema interface like this:

    interface Table extends HasName, HasAlias, HasOtherSchemaProperties {}

Then we can re-use the existing trait methods (e.g. printNameAndAlias()) with no extra effort or coupling. So this would work out-of-the-box:

    Schema schema = ...;
    printNameAndAlias(schema);

The trait scheme is used heavily in the open-source project Speedment that is a stream based ORM tool and runtime. Check out the actual Table and Column code here.

Do this:

    
    interface Table extends HasName, HasAlias, HasOtherTableProperties {}
    interface Column extends HasName, HasAlias, HasOtherColumnProperties {}
    
    interface HasName {
        void setName(String name);
        String getName();
    }
    
    interface HasAlias {
        void setAlias(String name);
        String getAlias();
    }

    public <T extends HasName & HasAlias> void printNameAndAlias(T item) {
        System.out.format("Name=%2, Alias=%s%n", item.getName(), item.getAlias());
    }

Don't do this:

    interface Table {
        void setName(String name);
        String getName();
        void setAlias(String name);
        String getAlias();
        ... other table specific methods
    }
    interface Column {
        void setName(String name);
        String getName();
        void setAlias(String name);
        String getAlias();
        ... other column specific methods
    }

    public void printNameAndAlias(Table item) {
        System.out.format("Name=%2, Alias=%s%n", item.getName(), item.getAlias());
    }

    public void printNameAndAlias(Column item) {
        System.out.format("Name=%2, Alias=%s%n", item.getName(), item.getAlias());
    }

    public void printNameAndAlias(Schema item) {
        System.out.format("Name=%2, Alias=%s%n", item.getName(), item.getAlias());
    }



Read more in the original DZone article at https://dzone.com/articles/using-traits-in-java-8

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.

Wednesday, December 7, 2016

Day 7, Java Holiday Calendar 2016, Access Databases with Streams

7. Access Databases with Streams


Today's tips is about querying databases using Java 8 streams. By adding both a runtime and plugin dependency to open-source Speedment in you applications Maven POM file, you get access to standard stream implementations of all the database's tables. For MySQL, your POM file could look like this:

<properties>
    <speedment.version="">3.0.1</speedment.version>
    <db.groupid>mysql</db.groupid>
    <db.artifactid>mysql-connector-java</db.artifactid>
    <db.version>5.1.39</db.version>
</properties>

<build>
    <plugins>

        <plugin>
            <groupid>com.speedment</groupid>
            <artifactid>speedment-maven-plugin</artifactid>
            <version>${speedment.version}</version>
            <dependencies>
                <dependency>
                    <groupid>${db.groupId}</groupid>
                    <artifactid>${db.artifactId}</artifactid>
                    <version>${db.version}</version>
                </dependency>
            </dependencies> 
        </plugin>

    </plugins>
</build>
<dependencies>

    <dependency>
        <groupid>com.speedment</groupid>
        <artifactid>runtime</artifactid>
        <version>${speedment.version}</version>
        <type>pom</type>
    </dependency>
    <dependency>
        <groupid>${db.groupId}</groupid>
        <artifactid>${db.artifactId}</artifactid>
        <version>${db.version}</version>
    </dependency>

</dependencies>

Read more on how to configure your POM file for other database types here which is also the place to be if you want to learn more on Speedment and how to write Speedment applications.

Do this:

users.stream()
    .filter(EMAIL.endsWith(".com"))
    .forEach(System.out::println);

Don't do this:

   Connection conn = null;
   Statement stmt = null;
   try {
      //STEP 2: Register JDBC driver
      Class.forName("com.mysql.jdbc.Driver");

      //STEP 3: Open a connection
      conn = DriverManager.getConnection(DB_URL, USER, PASS);
      
      //STEP 4: Execute a query
      stmt = conn.createStatement();

      String sql = "SELECT id, first, last, age, email FROM user";
      ResultSet rs = stmt.executeQuery(sql);
      //STEP 5: Extract data from result set
      while(rs.next()){
         //Retrieve columns
         int id  = rs.getInt("id");
         int age = rs.getInt("age");
         String first = rs.getString("first");
         String last = rs.getString("last");
         String email = rs.getString("email");

         if (email.endsWith(".com")) {
             //Display values
             System.out.print("ID: " + id);
             System.out.print(", Age: " + age);
             System.out.print(", First: " + first);
             System.out.print(", Last: " + last);
             System.out.println(", E-mail: " + email);
         }
      }
      rs.close();
   } catch(SQLException se){
      //Handle errors for JDBC
      se.printStackTrace();
   } catch(Exception e){
      //Handle errors for Class.forName
      e.printStackTrace();
   } finally {
      //finally block used to close resources
      try{
         if(stmt!=null)
            conn.close();
      } catch(SQLException se){
      }// do nothing
      try{
         if(conn!=null)
            conn.close();
      }catch(SQLException se){
         se.printStackTrace();
      }
   }


Read more in the original DZone article at https://dzone.com/articles/use-smart-streams-with-your-database-in-2-minutes

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.

Tuesday, December 6, 2016

Day 6, Java Holiday Calendar 2016, Lazy

6. Be Lazy With Java 8




Today's tips is about lazy initialization. Sometimes, we want our classes to do only what is absolutely necessary and nothing more. Immutable classes are particularly good candidates for laziness. Speedment, a Stream ORM Java Toolkit and Runtime, is using Lazy internally and you can find the complete Lazy source code here. Its free so steal it!

By copying this small Lazy class:

public final class Lazy<T> {

    private volatile T value;

    public T getOrCompute(Supplier<T> supplier) {
        final T result = value;  // Read volatile just once...
        return result == null ? maybeCompute(supplier) : result;
    }

    private synchronized T maybeCompute(Supplier<T> supplier) {
        if (value == null) {
            value = requireNonNull(supplier.get());
        }
        return value;
    }

}

You Can Do This:

public class Point {

    private final int x, y;
    private final Lazy<String> lazyToString;

    public Point(int x, int y) {
        this.x = x; 
        this.y = y;
        lazyToString = new Lazy<>();
    }

    @Override
    public String toString() {
        return lazyToString.getOrCompute( () -> "(" + x + ", " + y + ")");
    }

    // The calculation of the toString value is only done once
    // regardless if toString() is called one or several times.
    //
    // If toString() is never called, then the toString value is never
    // calculated.

}

Read more in the original article at http://minborgsjavapot.blogspot.com/2016/01/be-lazy-with-java-8.html

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.

Monday, December 5, 2016

Day 5, Java Holiday Calendar 2016, CRUD Operations

5. CRUD Operations


Today’s tip is an introduction on how to use open-source Speedment to expand the Java 8 Streams to support Creating, Reading, Updating and Deleting database entities.

Head out to Speedment's GitHub page to see how to modify your project's POM file. Once you done the changes, you can connect to an existing database and generate Java code automatically from the database's meta information (like columns and tables). Once completed, your Java Streams becomes much more feature full and you can:

Do This:

hares.stream()
  .filter(Hare.NAME.equal("Harry"))
  .map(Hare.COLOR.setTo("Brown"))
  .forEach(hares.updater()); 

  // Sets the color to "Brown" for all hares named "Harry" in the DB

Read more on DZone at https://dzone.com/articles/database-crud-operations-in-java-8-streams

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.

Sunday, December 4, 2016

Creating Maps With Named Lambdas


The Magical Map

Wouldn't it be great if we could create Java maps like this?

Map<String, Integer> map = mapOf(
      one -> 1,
      two -> 2
);

Map<String, String> map2 = mapOf(
      one -> "eins",
      two -> "zwei"
);



Well, we can! Read this post and learn more about lambdas and how we can get the name of their parameters.

The solution

By introducing the following interface we get the functionality above.

public interface KeyValueStringFunction<T> extends Function<String, T>, Serializable {

    default String key() {
        return functionalMethod().getParameters()[0].getName();
    }

    default T value() {
        return apply(key());
    }

    default Method functionalMethod() {
        final SerializedLambda serialzedLabmda = serializedLambda();
        final Class<?> implementationClass = implementationClass(serialzedLabmda);
        return Stream.of(implementationClass.getDeclaredMethods())
            .filter(m -> Objects.equals(m.getName(), serialzedLabmda.getImplMethodName()))
            .findFirst()
            .orElseThrow(RuntimeException::new);
    }

    default Class<?> implementationClass(SerializedLambda serializedLambda) {
        try {
            final String className = serializedLambda.getImplClass().replaceAll("/", ".");
            return Class.forName(className);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    default SerializedLambda serializedLambda() {
        try {
            final Method replaceMethod = getClass().getDeclaredMethod("writeReplace");
            replaceMethod.setAccessible(true);
            return (SerializedLambda) replaceMethod.invoke(this);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @SafeVarargs
    static <V> Map<String, V> mapOf(KeyValueStringFunction<V>... mappings) {
        return Stream.of(mappings).collect(toMap(KeyValueStringFunction::key, KeyValueStringFunction::value));
    }

}

Limitations

We can only create maps with keys that are of type String (or anything super String like CharSequence, Serializable or Comparable<String>) because obviously lambda names are strings.

We must use a Java version that is higher than Java 8u80 because it was at that time lambda names could be retrieved run-time.

The most annoying limitation is that we have to compile (i.e. "javac") our code with the "-parameter" flag or else the parameter names will not be included in the run time package (e.g. JAR or WAR). We can do this automatically by modifying our POM file like this:

          <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <compilerArgs>
                        <arg>-Xlint:all</arg>

                        <!-- Add this line to your POM -->
                        <arg>-parameters</arg>
                    </compilerArgs>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>

If you forget to add the "-parameter" flag, the Java runtime will always report a default name of "arg0" as the name of the parameter. This leads to that the maps will (at most) contain one key "arg0", which is not what we want.

Opportunities

The values, can be of any type. In particular they can be other maps, enabling us to construct more advanced map hierarchies. We could, for example, create a map with different countries with values that are also maps containing the largest towns and how many inhabitants each city has like this:


Map<String, Map<String, Integer>> map3 = mapOf(
            usa -> mapOf(
                new_york    -> 8_550_405,
                los_angeles -> 3_971_883,
                chicago     -> 2_720_546
            ),
            canada -> mapOf(
                toronto  -> 2_615_060,
                montreal -> 1_649_519,
                calgary  -> 1_096_833
            )
        );


Keep on mapping!


Day 4, Java Holiday Calendar 2016, RemoveIf

4. Use RemoveIf in Java Collections



Today's tips is to use the removeIf() method (that all collection classes like List have) rather than manually iterating over the elements and remove them. For large data sets, removeIf() can be orders of magnitudes faster than other ways. It also looks much better in your code. Why? Read more here and see for your self!

Do This:

items.removeIf(i -> predicate(i));

Don't Do This:

for (Iterator it = items.iterator(); it.hasNext();) {  
    if (predicate(it.next())) {
        it.remove();    
    }
}

Read more in the original article at http://javadeau.lawesson.se/2016/09/java-8-removeif.html

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.