Writing this blog sometimes requires experimentation and other times requires exploration of alternatives. I use Git as the version control system (VCS) for this. Git is one of the new(er) generation distributed version control systems (DVCS). Git is quite powerful, but does require some time getting used to not only the commands but various workflows as well.
For my blog, alternative solutions go into their own branches. In fact, each entry goes into into own branch. If I decide to move ahead with the change in the master “blog” project(s), then I rebase the master branch. With Git I get all the benefits of a VCS with out much overhead: setting up server, committing partial work, having multiple versions, etc.
I would encourage you to give Git (or one of the newer DVCSs) a try for your real or toy projects.
I want to pass in a collection and use that collection in an IN clause. For example, given a collection of identifiers (ids), I want a collection of products that match those identifiers. Hibernate supports this by allowing the in clause to be a parameter as shown in the example below:
1: Collection<Integer> aIds = Arrays.asList(p1.getId(), p2.getId(), p3.getId());
2: ...
3: String s = "select p from Product p where p.mId in (:aIds)";
4: List<Product> aProducts = mManager.createQuery(s).setParameter("aIds", aIds).getResultList();
In the above example, aIds is the collection parameter used in the IN clause. The SQL generated by Hibernate is:
1: select
2: product0_.PRODUCT_ID as PRODUCT1_0_
3: from
4: PRODUCT product0_
5: where
6: product0_.PRODUCT_ID in (? , ? , ?)
Hibernate allows me to take this one step further. The Parameter IN clause can not only be primitive types but entities as well. For example, given a collection of products, I want a collection of order line items that match those products as shown in the example below:
1: String aQuery = "select o from OrderLineItem o where o.mProduct in (:aProducts)";
2: List<OrderLineItem> aOrderLineItems =
3: mManager.createQuery(aQuery).setParameter("aProducts", aProducts).getResultList();
In the above example, aProducts is the collection parameter used in the IN clause. The SQL generated by Hibernate is:
1: select
2: orderlinei0_.ORDER_LINE_ITEM_ID as ORDER1_2_, orderlinei0_.PRODUCT_ID as PRODUCT2_2_
3: from
4: ORDER_LINE_ITEM orderlinei0_
5: where
6: orderlinei0_.PRODUCT_ID in (? , ?)
Pretty cool!
Hibernate nicely supports enum ordinal type and string type out of the box as defined in the Java Persistence API (JPA) specification. But, sometimes with legacy databases you need custom enum mapping.
There is lot of information out there, but the following are the two most useful:
So much meta information is specified for a simple enum in the above links. Wow! Something just doesn’t feel right about it. If I default / hardcode the identifierMethod and valueOfMethod, I can get it look like the following:
1: @Column(name = "ORDER_TYPE")
2: @Type(type = "ms.EnumUserType",
3: parameters = {@Parameter(name = "enumClass", value = "ms.domain.Order$OrderType")})
4: private OrderType mOrderType;
Still, I am specifying redundant information in value because I should be able to figure that out by the declared type of the member variable OrderType in this case.
I am using the following:
When the test failed I got the following exception:
1: java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/DescriptionV
2: at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18)
3: at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
4: at ms.EnumExample.saveEnum(EnumExample.java:19)
5: at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
6: at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
7: at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
8: at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
9: at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
10: at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
11: at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
12: at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
13: at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
14: at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
15: at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
16: at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
17: at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
18: at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
19: at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
20: at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
21: at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
22: at com.intellij.rt.junit4.Junit4TestMethodAdapter.run(Junit4TestMethodAdapter.java:62)
23: at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:40)
24: at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
25: at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
26: at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
27: at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
I guess hamcrest ships with JUnit.
One solution is to download junit-dep-4.7.jar and make it part of the project. Then everything works fine!
Another solution that I haven’t tried is to remove hamcrest jar and just rely on junit 4.7, unless of course you need something specific from the version of hamcrest.
In my last blog entry, I discussed One-to-One relationship in Hibernate. The problem was the extra SQL statements! One solution is to use Embeddable and Embedded concepts.
The ProductDescription becomes an Embeddable instead of an entity. Other than that, it pretty much remains the same as shown below.
1: @Embeddable
2: public class ProductDescription implements Serializable {
3: @Column(name = "DESCRIPTION", table = "PRODUCT_DESC"
4: private String mDescrption;
5:
6: ...
7: }
The Product instead of having one-to-one, has an embedded ProductionDescription. I also indicate the secondary table with @SecondaryTable annotation.
1: @Entity
2: @Table(name = "PRODUCT")
3: @SecondaryTable(name = "PRODUCT_DESC")
4: public class Product {
5: ...
6:
7: @Embedded
8: private ProductDescription mProductDescription;
9:
10: ...
11: }
Running with the same example as in the previous blog entry, the SQL generated includes an outer join and the number of SQL statements is reduced!
1: select
2: product0_.PRODUCT_ID as PRODUCT1_0_, product0_1_.DESCRIPTION as DESCRIPT1_1_
3: from
4: PRODUCT product0_
5: left outer join PRODUCT_DESC product0_1_ on product0_.PRODUCT_ID=product0_1_.PRODUCT_ID
In the previous blog entry, I mentioned, almost lamented, about all those blog entries and forum posts that describe the problem, but no decent solution. Now, you can include this blog entry to that list!
Consider the following one-to-one relationship between Product and ProductDescription: Product can have optional ProductDescription. The following is the Product side:
1: public class Product {
2: ...
3:
4: @OneToOne(mappedBy = "mProduct", fetch = FetchType.LAZY, optional = true)
5: private ProductDescription mDescription;
6:
7: ...
8: }
The following is the ProductDescription side:
1: public class ProductDescription {
2: ...
3:
4: @OneToOne(optional = false)
5: @JoinColumn(name = "PRODUCT_ID")
6: private Product mProduct;
7:
8: ...
9: }
Assuming the product table contains two products. One without description and one with description. Hibernate generates the following SQL:
1: select product0_.PRODUCT_ID as PRODUCT1_0_ from PRODUCT product0_
2: select productdes0_.PRODUCT_ID as PRODUCT1_1_1_, productdes0_.DESCRIPTION as DESCRIPT2_1_1_, product1_.PRODUCT_ID as PRODUCT1_0_0_ from PRODUCT_DESC productdes0_ inner join PRODUCT product1_ on productdes0_.PRODUCT_ID=product1_.PRODUCT_ID where productdes0_.PRODUCT_ID=?
3: select productdes0_.PRODUCT_ID as PRODUCT1_1_1_, productdes0_.DESCRIPTION as DESCRIPT2_1_1_, product1_.PRODUCT_ID as PRODUCT1_0_0_ from PRODUCT_DESC productdes0_ inner join PRODUCT product1_ on productdes0_.PRODUCT_ID=product1_.PRODUCT_ID where productdes0_.PRODUCT_ID=?
The ProductDescription in Product is lazy, so why does hibernate try to load the descriptions?
The are many blogs, forum messages, etc. for this problem. They describe hacks and other ideas, but none of them is quite acceptable.
Do you love sugar? Syntactic Sugar? If you do then you would like Hamcrest. Hamcrest makes unit tests little more readable.
The following is a simple JUnit test:
1: @Test
2: public void SimpleBoolean() {
3: assertEquals(true, coolTest());
4: }
Now, using Hamcrest:
1: @Test
2: public void SimpleBoolean_Hamcrest() {
3: assertThat(coolTest(), is(true));
4: }
Notice the usage of static imports in both the versions. Also, in the Hamcrest version the actual and expected are switched. Some people think that the Hamcrest version is more natural. Is this syntactic sugar worth it? To help you decide checkout the following additional example:
1: @Test
2: public void Comparison() {
3: assertEquals(true, commission() > 10);
4: }
The Hamcrest version is:
1: @Test
2: public void Comparison_Hamcrest() {
3: assertThat(commission(), is(greaterThan(10)));
4: }
The following is an example of comparing BigDecimals. Usually, code like this is pretty ugly.
1: @Test
2: public void CompareBigDecimal() {
3: assertEquals(true, new BigDecimal("0.99").compareTo(price()) == 0);
4: }
And the Hamcrest version:
Note: Just ordering comparison was added in the later version of Hamcrest.
1: @Test
2: public void CompareBigDecimal_Hamcrest() {
3: assertThat(price(), comparesEqualTo(new BigDecimal("0.99")));
4: }
I have seen code that uses Hamcrest assertThat as assertEquals, but I think that defeats the purpose. In this case, may be the developer is missing the point of syntactic sugar?
Consider the following piece of code that does string concatenation.
1: public String validateOrderLineItem(OrderLineItem aOrderLineItem) {
2: if (aOrderLineItem.getPrice() == null) {
3: return "The order line item for product: " + aOrderLineItem.getProduct().getDescription() +
4: " for order id : " + aOrderLineItem.getOrder().getId() + " must not be null!";
5: }
6: return null;
7: }
I am not a big fan of such string concatenation. Such strings are harder to read and maintain. They are also potential performance and memory problems.
I always try to replace the code above with something that looks like this:
1: private static final String INVALID_PRICE =
2: "The order line item for product: %s for order id : %s must not be null!";
3:
4: public String validateOrderLineItem2(OrderLineItem aOrderLineItem) {
5: if (aOrderLineItem.getPrice() == null) {
6: return String.format(INVALID_PRICE, aOrderLineItem.getProduct().getDescription(),
7: aOrderLineItem.getOrder().getId());
8: }
9: return null;
10: }
At least the message is much easier to read!
There are couple of other alternatives like using MessageFormat and templating languages, but they are over kill for this example.
This example is in Java, but is equally applicable to C# and other languages.
I added a error provider in a form and added some validation logic. But, when I want to cancel and close the form, the form doesn’t close until the error is fixed. The way to fix this to set the Cancel property of the form closing event to be false.
How about if I have a cancel button and would like the same behavior as above? The trick now is to set the CausesValidation property of the cancel button to be false. Now, if you try this and it still doesn’t work, then just make sure that all the (parent) containers, excluding the form, of the cancel button also have the CausesValidation property as false.
One of the dependency-breaking techniques described by Michael C. Features in his book “Working Effectively With Legacy Code” is Parameterized Method. I use this quite often to make code testable. My typical usage looks something like the following. Let’s say, I have the following method:
1: public void ComplicatedMethod(View view)
2: {
3: // some code here
4: if (view.Available)
5: Console.WriteLine("more complicate code");
6: // even more complicated code
7: }
What makes it hard to test this method is the instance of view. The view might not be easy to create. The view may have its own dependencies and so forth. However, notice how the view is being used. The view is only being used to check for a condition. So, let’s apply Parameterized Method refactoring to it.
1: public void ComplicatedMethod(View view)
2: {
3: ComplicatedMethod(view.Available);
4: }
5:
6: public void ComplicatedMethod(bool available)
7: {
8: // some code here
9: if (available)
10: Console.WriteLine("more complicate code");
11: // even more complicated code
12: }
Now, the over-loaded method that takes a bool instead of the view is easy to test!
The above example is in C#, but equally applicable to Java or anything else for that matter. There are many other alternatives to Parameterized Method as well.