Here’s a handy reference for various patterns
Tree Linux Command
Where have you been, all my life?
vinay@proton ~/workspaces/defaultworkspace/neo4j-tutorial $ tree src/koan/java
src/koan/java
└── org
└── neo4j
└── tutorial
├── Koan01.java
├── Koan02.java
├── Koan03.java
├── Koan04.java
├── Koan05.java
├── Koan06.java
├── Koan07.java
├── Koan08a.java
├── Koan08b.java
├── Koan08c.java
├── Koan08d.java
├── Koan08e.java
├── Koan09.java
├── Koan10.java
├── Koan11.java
├── koan12
│ └── HomePlanetUnmanagedExtension.java
├── Koan12.java
├── koan13
│ └── AwesomenessServerPlugin.java
├── Koan13.java
├── koan14
│ ├── SalaryUnmanagedExtension.java
│ └── UserNameAndPasswordForSalariesSecurityRule.java
├── Koan14.java
├── matchers
│ ├── CharacterAutoIndexContainsSpecificCharacters.java
│ ├── ContainsOnlyHumanCompanions.java
│ ├── ContainsOnlySpecificActors.java
│ ├── ContainsOnlySpecificInts.java
│ ├── ContainsOnlySpecificNodes.java
│ ├── ContainsOnlySpecificSpecies.java
│ ├── ContainsOnlySpecificStrings.java
│ ├── ContainsOnlySpecificTitles.java
│ ├── ContainsSpecificCompanions.java
│ ├── ContainsSpecificNumberOfNodes.java
│ ├── ContainsWikipediaEntries.java
│ └── PathsMatcher.java
└── server
└── rest
└── domain
├── EpisodeSearchResult.java
└── EpisodeSearchResults.java
10 directories, 36 files
HTML Instant : Real-Time HTML Editor
This tool is good for deciphering all those pesky log messages that get returned as HTML formatted strings.
Hibernate and False Duplicates
This issue hit me today (well documented at http://glueclue.blogspot.com/2006/02/hibernate-duplicates-with-join-fetch.html).
From what I understand, one way around this is to use “DISTINCT” in the HQL, but in my case this wasn’t possible because of the type of data in my persisted beans.
I chose to use query.uniqueResult() since I expected a unique result. In any case, a close miss.
A variation of a map that supports querying on multiple keys
Last evening, for unknown reasons, I started pondering how easy if would be to implement a map data structure that could be queried using different means. For example, what if the AddressBean described below could be queried by name, owner etc etc . After some aimless coding, this is what I came up. Not strictly generic compliant, but close enough for a proof of concept.
The implementation I came up with is, strictly speaking, not key based, rather bean-property based as defined by the chosen implementation of the interface ObjectKeyGenerator. In that sense, it is more like a variation on hashkeys. Note, however, that it doesn’t enforce uniqueness, so if there were multiple owners with name “a” in the described example, the last inserted one would overwrite peior entries mapped to that key. Easily addressable via a multimap implementation, but beyond the scope of this post, however.
A simple application demoing the use of the datastructure.
package com.vgb.multikeymap;
public class AddressBeanApp {
/**
* @param args
*/
public static void main(String[] args) {
AddressBean a1 = new AddressBean("a", "street 1", 1000, 101, 75080);
AddressBean a2 = new AddressBean("b", "street 1", 1002, 102, 75080);
MultiKeyMap<AddressBean> map = new AddressMultKeyMap<AddressBean>();
map.put(a1);
map.put(a2);
System.out.println(map.get(AddressMultKeyMap.OWNER, "a"));
System.out.println(map.get(AddressMultKeyMap.SUITE, 101));
System.out.println(map.get(AddressMultKeyMap.OWNER, "b"));
System.out.println(map.get(AddressMultKeyMap.OWNER, "foo"));
System.out.println(map.get("INVALID_TYPE", "a"));
}
}
The bean that is stored.
package com.vgb.multikeymap;
public class AddressBean {
private String owner;
private String street;
private int houseNum;
private int suite;
private int zipCode;
public AddressBean(String owner, String street, int houseNum, int suite, int zipCode) {
super();
this.owner = owner;
this.street = street;
this.houseNum = houseNum;
this.suite = suite;
this.zipCode = zipCode;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public int getHouseNum() {
return houseNum;
}
public void setHouseNum(int houseNum) {
this.houseNum = houseNum;
}
public int getSuite() {
return suite;
}
public void setSuite(int suite) {
this.suite = suite;
}
public int getZipCode() {
return zipCode;
}
public void setZipCde(int zipCode) {
this.zipCode = zipCode;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
@Override
public String toString() {
return "AddressBean [owner=" + owner + ", street=" + street + ", houseNum=" + houseNum + ", suite=" + suite + ", zipCode=" + zipCode + "]";
}
}
The implementation of the multi-key map with key definitions explicitly coded in
package com.vgb.multikeymap;
import java.util.AbstractMap.SimpleEntry;
public class AddressMultKeyMap<V> extends MultiKeyMap<AddressBean> {
public static final String OWNER = "owner";
public static final String SUITE = "suite";
public AddressMultKeyMap() {
super();
}
@SuppressWarnings("unchecked")
@Override
public void generateTypesAndKeysFromValues() {
initInnerMapItem(new SimpleEntry<String, ObjectKeyGenerator<?>>(SUITE, new ObjectKeyGenerator<AddressBean>() {
@Override
public Object extractKey(AddressBean data) {
return data.getSuite();
}
}));
initInnerMapItem(new SimpleEntry<String, ObjectKeyGenerator<?>>(OWNER, new ObjectKeyGenerator<AddressBean>() {
@Override
public Object extractKey(AddressBean data) {
return data.getOwner();
}
}));
}
};
The abstract class that does all the heavy lifting
package com.vgb.multikeymap;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public abstract class MultiKeyMap<V> {
private Map<String, ObjectKeyGenerator<V>> typeKeyGenMap = new HashMap<String, ObjectKeyGenerator<V>>();
protected Map<String, Map<Object, V>> mainMap = new HashMap<String, Map<Object, V>>();
public MultiKeyMap() {
generateTypesAndKeysFromValues();
}
public Map<Object, V> getMap(String type) {
if (mainMap.containsKey(type)) {
return mainMap.get(type);
}
return null;
}
public V get(String type, Object key) {
Map<Object, V> myMap = getMap(type);
if (myMap == null) {
return null;
}
return myMap.get(key);
}
public void put(V value) {
for (Entry<String, ObjectKeyGenerator<V>> e : typeKeyGenMap.entrySet()) {
String type = e.getKey();
Object key = e.getValue().extractKey(value);
mainMap.get(type).put(key, value);
}
}
public abstract void generateTypesAndKeysFromValues();
private Map<Object, V> createInnerMap() {
return new HashMap<Object, V>();
}
protected void initInnerMap(Entry<String, ObjectKeyGenerator>... vargs) {
for (Entry<String, ObjectKeyGenerator> entry : vargs) {
if (entry.getKey() == null || entry.getKey().trim().isEmpty()) {
continue;
}
typeKeyGenMap.put(entry.getKey(), entry.getValue());
mainMap.put(entry.getKey(), createInnerMap());
}
}
protected void initInnerMapItem(Entry<String, ObjectKeyGenerator<?>> e1) {
if (e1.getKey() == null || e1.getKey().trim().isEmpty()) {
return;
}
typeKeyGenMap.put(e1.getKey(), (ObjectKeyGenerator<V>) e1.getValue());
mainMap.put(e1.getKey(), createInnerMap());
}
}
An interface defining how the key extraction behavior
package com.vgb.multikeymap;
public interface ObjectKeyGenerator<V> {
public Object extractKey(V data);
}
A helper transport class for input parameter pairs
package com.vgb.multikeymap;
public class TypeObjectKeyGenPair<V> {
String type;
ObjectKeyGenerator<V> keyGen;
public TypeObjectKeyGenPair(String type, ObjectKeyGenerator<V> keyGen) {
super();
this.type = type;
this.keyGen = keyGen;
}
public String getType() {
return type;
}
public ObjectKeyGenerator<V> getKeyGen() {
return keyGen;
}
}
Generating “CREATE TABLE” SQL from a JPA / Hibernate Annotated POJO
Here’s an easy snippet of code to perform this task. It output’s the “CREATE TABLE” adjust for the desired SQL dialect
public void entityToSQL() throws Exception{
Configuration cfg = new Configuration();
cfg.addAnnotatedClass(MyPOJO.class);
String[] lines = cfg.generateSchemaCreationScript(
new SQLServer2008Dialect());
for (String line : lines) {
System.out.println(line);
}
}
Oh, how true
This terminal banner brought a smile to my face this evening, nice to know I’m not alone in the universe.
___________________________________
( "Maybe not all versions of nvidia )
( settings behave gracefully?" )
( )
( Husse Apr 22 2007 )
-----------------------------------
o
o
.--.
|o_o |
|:_/ |
// \ \
(| | )
/'\_ _/`\
\___)=(___/
..
Fix: Eclipse Debugger Hanging on Debug
Oftentimes, when running an Eclipse Java Debug session, the debugger breaks on .finalize() methods etc etc. This is distracting.To fix this annoyance, Navigate to Window->Preferences->Java->Debug . Uncheck the “Suspend Exceptions on Uncaught Exceptions” and restart your debug session.
Adding a class to a jar
Pretty easy to do
c:\junk>dir Volume in drive C is OSDisk Volume Serial Number is 3C36-1DA9 Directory of c:\junk 12/07/2011 09:58 AM <DIR> . 12/07/2011 09:58 AM <DIR> .. 12/07/2011 09:56 AM <DIR> com 12/07/2011 09:29 AM <DIR> etc 12/07/2011 08:36 AM 295,229 myjar.jar 12/07/2011 09:55 AM <DIR> tmp 1 File(s) 295,229 bytes 5 Dir(s) 186,890,629,120 bytes free c:\junk>jar -uf myjar.jar com\xxx\jbapi\myclass.class c:\junk>dir Volume in drive C is OSDisk Volume Serial Number is 3C36-1DA9 Directory of c:\junk 12/07/2011 10:00 AM <DIR> . 12/07/2011 10:00 AM <DIR> .. 12/07/2011 09:56 AM <DIR> com 12/07/2011 10:00 AM <DIR> etc 12/07/2011 10:00 AM 297,207 jbapi-2.0.jar 12/07/2011 09:55 AM <DIR> tmp 1 File(s) 297,207 bytes 5 Dir(s) 186,890,010,624 bytes free c:\junk>
Nice class decompiling tool / GUI
This appears to have an eclipse plugin too for those pesky “No source Found” errors.
http://java.decompiler.free.fr/