Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Wednesday, January 07, 2009

The Nasty JPA "Unknown abstract schema type" error

I been trying to debug the following error for days, and it drive me nuts!

The problem: JPA refuse to compile one of my NamedQuery, and throws the following error:

Error compiling the query [UserVO.findByUserName: SELECT u FROM UserVO u WHERE u.name = :name]. Unknown abstract schema type [UserVO]

After numerous Google search, I conclude that JPA will throw "Unknown abstract schema type" when JPA fail locate your entity class". Most often, this type error occurs when:
  • Developer have put down database table name instead of Entity Class name in the JPA query. eg. if we have a EntityClass UserVO which map to table name users, the query "SELECT u from users u" will throw the above exception.
  • When running JPA in standalone, or not JavaEE container(such as Tomcat 5/6), they forgot to explicit list all entities class in the persistence.xml, thus JPA fail to locate the entities when compile the query.
None of above apply to my case, I have explicit listed all my entities class in the persistence.xml
and I am sure my JPA query is valid. I have tested my code with different JPA implementations, but always resulted the same error..

Here my UserVO class


@Entity(name = "users")
@NamedQuery(name = "UserVO.findByUserName",
query = "SELECT u FROM UserVO u WHERE u.name = :name")
public class UserVO extends implements Serializable {

|
|
}


If I remove the NamedQuery, my JPA able to work as expected, i.e I am able to insert, delete, and update UserVO object.
Now, to all my smart reader, can u spot what's wrong in my code? Scroll down for answer.


|
|
|
|
|
|
|

Answer: The culprit is the Entity annotation, I explicit name the UserVO entity as users, which JPA have no problem to map the UserVO to users database table, but have problem to compile the JPA Query, because it can't find the UserVO entity in the JPA context, as the suppose UserVO entity have rename to users entity by me, got it, or confuse..

To resolve this, just add a @Table annotation with the table name, as shown code below:


@Entity
@Table(name = "users")
@NamedQuery(name = "UserVO.findByUserName",
query = "SELECT u FROM UserVO u WHERE u.name = :name")
public class UserVO extends implements Serializable {

|
|
}


Cheers, Happy New Year!!!!

Tuesday, April 15, 2008

A quick update on JPA Boolean Magic Converter

Some update on changes:
  • Fixed the bug of Null pointer exception, when JPA return null on the annotated field.
  • Introduce a new properties call ifNull, which allows user to configure what to return if JPA returns null, it expect enum of org.jbpcc.util.jpa.ReturnType, which have values of ReturnType.True, ReturnType.FALSE, and ReturnType.Null,. The default value of ifNull is ReturnType.Null
Thus as an example, assuming we have model class define as below:

package org.jbpcc.domain.model;

import javax.persistence.Entity;
import javax.persistence.Id;
import org.jbpcc.util.jpa.BooleanMagic;
import org.jbpcc.util.jpa.BooleanMagic.ReturnType;

@Entity
public class SomeVO {
@Id
private Integer id;
@BooleanMagic(trueValue = "Yes", falseValue = "No",
columnName = "OVERDUED", ifNull = ReturnType.FALSE)
private transient Boolean overdued;

public Boolean isOverdued() {
return overdued;
}

public void setOverdued(Boolean overdued) {
this.overdued = overdued;
}
}

Java APT with JPABooleanMagicConverter factory, code above will be converted to:

@Entity
public class SomeVO {
@Id
private Integer id;
private transient Boolean overdued;
//--- Lines below are generated by JBPCC BooleanMagicConvertor PROCESSOR
//--- START :

@Column(name="OVERDUED")
private String magicBooleanOverdued;


public Boolean isOverdued() {
if (this.magicBooleanOverdued == null)
return false;
return this.magicBooleanOverdued.equals("Yes") ? Boolean.TRUE : Boolean.FALSE;
}

public Boolean getOverdued() {
if (this.magicBooleanOverdued == null)
return false;
return this.magicBooleanOverdued.equals("Yes") ? Boolean.TRUE : Boolean.FALSE;
}

public void setOverdued(Boolean trueFlag) {
this.magicBooleanOverdued = trueFlag ? "Yes" : "No";
}
//--- END
//--- GENERATED BY JBPCC BooleanMagicConvertor PROCESSOR

}


That's all, as usual, you could find the JPABooleanMagicConverter binary at http://code.google.com/p/jbpcc/downloads/list.

Do share me your thoughts and comments, happy coding

Sunday, April 13, 2008

A portable JPA Boolean Magic Converter

While doing some small POC with JPA, I am surprise to find out that the current Java Persistence API (JPA) standard does not mandate JPA provider to support data type conversion via annotation, not even a with simple boolean field. For reader who unfamiliar with JPa, what I means is, to persist and "JPA" manage a boolean field, JPA expect the database data type to be integer, where value of "1" means true, and value of "0" means false.

You got to be joking, right? Every "real life" programmer knows that, there are many existing database use different combination of char or string on a table boolean field, such as "True/False", "T/F", "Yes/No", "Y/N", "-1/0", and etc. Thus, as a "real life" programmer, I kind expect the JPA should allows me specific a boolean field via Annotation, such as example below:

@booleanField(trueValue="Yes", falseValue="No")
private Boolean enabled;

And to my surprise, the answer is nope!!!..So far only Hibernate JPA provider provide data type conversation. Daniel Pfeifer, have explain the problem in details, he also discuss some solutions to work around this stupid limitation at his blog, title "Type Conversation with JPA", do check it out.

Daniel's "manual mapping" idea, do solve the limitation. However, maybe it's just me, I just don't like the idea to temporary change a Boolean field to map with database data type (either char, string) in order to resolve the limitation, even we make the field private, this is just me. And I am stubborn, and old . :-)

Anywhere, after some research (Also, a good excuse to my manager to research how difficult to come out our own custom Java 5 annotation with custom Java APT process factory), I come out our own compile time annotation, called @BooleanMagic with our own BooleanMagicProcessorFactory, which I hope, shall temporary resolve the problem.

@BooleanMagic comprise of three attributes:
  • trueValue, specified the table boolean field true value here, such as "True", "T", "Yes"
  • falseValue, specified the table boolean field false value here, such as "False", "F","N"
  • columnName, tableColumn name;
Also please note that BooleanMagicProcessorFactory mandate any field annotated with @BooleanMagic annotation, must either annotated with @Transient annotation or with modifier transient.

Thus, as an example, assuming we have a boolean field called "enabled", which map to table "ENABLED" field, with boolean value of "True"/"false", we will specified our VO as below:

@Entity
public class SomeVO {
@Id
Integer id;
@BooleanMagic(trueValue="True", falseValue="false", columnName="ENABLED")
private transient Boolean enabled;

public Boolean isEnabled() {
return enabled;
}

public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
}

Using Java "APT" tool with JPABooleanMagicConverter factory, code above will be converted to:


@Entity
public class SomeVO {
@Id
Integer id;

private transient Boolean enabled;
//---
//--- Lines below are generated by JBPCC BooleanMagicConvertor PROCESSOR
//--- START :

@Column(name="ENABLED")
private String magicBooleanEnabled;

public Boolean isEnabled() {
return this.magicBooleanEnabled.equals("True") ? Boolean.TRUE : Boolean.FALSE;
}

public Boolean getEnabled() {
return this.magicBooleanEnabled.equals("True") ? Boolean.TRUE : Boolean.FALSE;
}

public void setEnabled(Boolean trueFlag) {
this.magicBooleanEnabled = trueFlag ? "True" : "false";
}

//--- END
//--- GENERATED BY JBPCC BooleanMagicConvertor PROCESSOR
}


Now, isn't that cool (haha, sorry, I am bit biased here). Btw, BooleanMagicConvertor is portable across JPA protable, and IMHO, this is a better interim solution till JPA make data conversation standard.

I decided to contribute my BooleanMagicConverter back to open source community, it's currently park under my open source project Java Batch Process Control Center, at http://code.google.com/p/jbpcc, you could either build from the source, or get the "BooleanMagicProcessorFactory.jar" from here.

Here an example of how to use the BooleanMagicConvertor using Ant 1.7 apt tasks, assuming all your entity class is declare at ${src.dir}/org/abc/domain/model directory, and you wants to output all generated call to ${basedir}/target directory
 <target name="preProcessJPABoolean" depends="buildJPABoolenProcessorFactory">
<apt srcdir="${src.dir}/org/abc/domain/model"
destdir="${build.classes.dir}"
classpath="./dist/BooleanMagicProcessorFactory.jar:./lib/Model_Dependent_thirdparty.jar"
debug="on"
compile="false"
factory="org.jbpcc.util.jpa.BooleanMagicProcessorFactory"
preprocessdir="${basedir}/target">
</apt>
</target>

That's all, do share me your thoughts and comments, cheers!

Thursday, March 27, 2008

I started yet another open source project



I decided to start another open source project name Java Batch Process Control Center (JBPCC). "What, another open source project again!, what happen to your suduko project?", some of u may ask. Well, the project still hosted at sourceforge, we just not going to maintain the project any more. Reason being, I am tired of suduko already, and there are far too many variance of suduko open source project exists. Sorry!

Anywhere, the idea of Java Batch Process Control Center is somehow continue from my original idea on "Automatic Remote Logging Management via JMX". by using Java 5 instrument API, developer able to "wrap" any Java base process, and automatically offer JMX monitoring and remote logging management functionalities, and the idea of JBPCC, is to deliver end user an AJAX web application to manage, monitor and schedule any those "wrap" processes.

Proposed Features:
  • An in-memory module for remote servers to register, execute, and manage batch processes.
  • Time-based and duration-based scheduling of any configured or registered batch process for execution.
  • Monitoring currently running processes, including resources used and logs.
  • Server management for configuration of servers that hold remote batch processes.
  • A simple rights-based user management module.

Our project is hosted at http://code.google.com/p/jbpcc , Please note that, as this is still a fairly new project, there isn't much user could download from our project repository. But, rest assure that, we will post project news, progress report, tutorial, even web cast here. So, stay tune..

Wish me luck!

Monday, November 05, 2007

Automatic Remote Logging Management via JMX.

Wow, the post title definitely sound “very technical”, and I do hope that it will attract more readers here. :-)

It all started a weeks ago, where I have accidentally discovered a “hidden JDK 5 treasure” (from Daniel Fuch, blogs http://blogs.sun.com/jmxetc/) , called java.lang.instrument, a Java package that provides services that allowing Java language agents to instrument programs running on the JVM. Most people use it for profiling, or pre-instrument purpose.


But I have a idea, why don't we create a logging management wrapper, which allows us to wrap any Java application, and provide us some logging management functionalities without any modification on our application source code. The logging agent will offer the following:

  • Abilities to change log level (debug, info, warning, error) on any configured logger dynamically without restart.
  • Abilities to locate any configured log output files.
  • Abilities to browse (either head, or tail) any configured log files.
Base on requirements above, I come out JMXMBean interface below:


public interface RemoteLoggingMBean {
  public void activateDebug(String loggerName);
public void activateInfo(String loggerName);
public void activateWarning(String loggerName);
public void activateError(String loggerName);
/**
* Retrieve current configured log output files base on given logger.
* The system will only return log files with the following appender
* org.apache.log4j.DailyRollingFileAppender, org.apache.log4j.FileAppender
* org.apache.log4j.RollingFileAppender;
* @param loggerName
* @return Array of file name with relataive file path points to current running directory.
*/
public String[] retrieveCurrentConfiguredLogFiles(String loggerName);
/**
* Similar to Unix head command, read a text file forward from the beggining
* of the file till it reaches line limit, or EOF
* @param fileName the logFileName.
* @param linesToRead, Number of line to be read.
* @return JMX CompositeData with the structure of StartFilePointer (SimpleType.Long),
* EndFilePointer(SimpleType.Long), LogMessages(SimpleType.String)
* @throws java.io.IOException
*/
public CompositeData headLog(String fileName, int linesToRead) throws OpenDataException, IOException;
public CompositeData headLog(String fileName, int linesToRead, long fromFilePointer) throws OpenDataException, IOException;
public CompositeData tailLog(String fileName, int linesToRead) throws OpenDataException, IOException;
public CompositeData tailLog(String fileName, int linesToRead, long fromFilePointer) throws OpenDataException, IOException;
}

The rest of code is delivered by using various JMX and Apache Log 4J API, which I am not going to discuss here, as this is obviously not JMX nor Java Logging tutorial.

If u interest, u could download the whole project source from here. Is not under any copy write protection. U are welcome to download it, modify it, change the author name, use it or distribute it to anyone. IMHO, The IT have to many unfair patents, or copy protection law, which in a way, have stop us on moving forward.

Anywhere, back to topic. To use the wrapper on any Java application that use Apache Log4J for logging, follows steps below:

  1. Either download the binary RemoteJMXLoggingAgent.jar, or build it from the source
  2. Put the binary to your application class path, make sure it sit together with log4j.jar
  3. Append the line at your Java Application startup script
"-javaagent:(deploy directory)/RemoteJMXLoggingAgent.jar
-Drmi.agent.port=AnyRMIPort (optional, default=3000)"


That's it, u application is now able to offer above Remote Logging management functionalities via JMX. To test this, open jconsole from any PC, and connect your remote application via the JMX URL below:
service:jmx:rmi:///jndi/rmi://hostname:rmi_port/remoteLoggerAgent

The Mbean on managing your application logger is called "org.coolboy.RemoteLoggingManager", have fun!


Tuesday, February 27, 2007

[quick tips] To Speedup your junit testing in Ant

If your development project get bigger, and have incorporated thousands of test cases, u may find that unit testing target getting slower and slower. It may come to a point your developers start to ignore test cases, or worst, don't write any test cases at all, as it will slow down build process.

Now, before u look into your unit testing code to improve the performance, why don't have a check on your Ant Junit Target (I discovered this accidentally yesterday, as I am frustrated by the slow build process). If u have setup ur Ant to fork a new JVM for unit testing target, by default, Ant will fork a new VM per Test Class, which is slow, and expansive (imagine forking 1000+ jvm for your project). To correct this, we just needs to set correct forkmode="perBatch".
i.e
junit fork="true" forkmode="perBatch"

My test result, before forkmode="perBatch", my test process take ~= 16 minutes
after, my test process take < 2 minutes

Cheers, and happy coding

Monday, February 12, 2007

[Tech Tips] Implementing Command Design Pattern via Spring Framework - Part II



The RemoteControl class needs to hold list of supported commands, and needs to delegate request to respective command class base on the pass in command string. Here is the RemoteControl source:

 1
2 package blog.coolboy.springexample.cp;
3
4 import java.util.List;
5 import java.util.HashMap;
6 import blog.coolboy.springexample.cp.command.CommandType;
7 import blog.coolboy.springexample.cp.command.Command;
8
9
10 public class RemoteControl {
11
12 private HashMap<String, Command> supportedCommands = null;
13
14 public RemoteControl() { }
15
16
17 public void setListOfSupportedCommands(List<Command> commandList) {
18 supportedCommands = new HashMap<String, Command>();
19 for(Command cmd : commandList) {
20 supportedCommands.put(
cmd
.getCommandType().getCommandString(),
cmd
);
21 }
22
23 }
24
25 public void execute(String cmdString) {
26 Command cmd = supportedCommands.get(cmdString);
27 if(cmd != null) {
28 cmd.execute();
29 } else {
30 System.out.println("The cmd->" +
cmdString
+ " is not supported!");
31 }
32 }
33
34 }
The RemoteControl will transfer a list of supported commands to internal HashMap using commandString as object key, thus, removing the needs of iterating commands list for each new command execution.

Here's the fun part, we will inject list of supported commands to the RemoteControl above using Spring XML configuration, as shown in code below:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>

<!-- listing of supported Commands here -->

<bean id="tvOnCommand"
class="blog.coolboy.springexample.cp.command.impl.TVOnCommand"/>
<bean id="tvOffCommand"
class
="blog.coolboy.springexample.cp.command.impl.TVOffCommand"/>
<bean id="lightOnCommand"
class="blog.coolboy.springexample.cp.command.impl.LightOnCommand"/>
<bean id="lightOffCommand"
class="blog.coolboy.springexample.cp.command.impl.LightOffCommand"/>

<bean id="remoteControl"
class
="blog.coolboy.springexample.cp.RemoteControl">
<property name="listOfSupportedCommands">
<list>
<ref bean="tvOnCommand"/>
<ref bean="tvOffCommand"/>
<ref bean="lightOnCommand"/>
<ref bean="lightOffCommand"/>
</list>
</property>
</bean>
</beans>


That's all, our remote control class is finished. To roll out new Command, developer just needs to
1. declare the new command type, and it's command string at the CommandType enum
2. implements the command, and
3. inject new command via Spring Configuration.


Here are remoteControlService class to test the remoteControl

 1 package blog.coolboy.springexample.cp;
2
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStreamReader;
6 import org.springframework.context.support.ClassPathXmlApplicationContext;
7 import org.springframework.context.ApplicationContext;
8 import org.springframework.jms.listener.DefaultMessageListenerContainer;
9
10 public class RemoteControlService {
11 public static void main(String [] args) {
12 ApplicationContext context =
new
ClassPathXmlApplicationContext("/conf/remoteControlConfig.xml");
13 RemoteControl remoteControl = (RemoteControl) context.getBean("remoteControl");
14 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
15 System.out.println("Remote Control Ready, enter 'Quit' to terminate the program");
16 String txtCommand;
17 try {
18 do {
19 System.out.print("Enter your command->");
20 txtCommand = reader.readLine();
21 if(txtCommand.equalsIgnoreCase("quit")) {
22 break;
23 } else {
24 remoteControl.execute(txtCommand);
25 }
26 System.out.println("");
27 } while(true);
28 } catch (IOException ex) {
29 ex.printStackTrace();
30 }
31
32 }
33 }
Here are the try run:
------------------

Remote Control Ready, enter 'Quit' to terminate the program
Enter your command->tv.on
Switching On TV
Enter your command->tv.off
Switching off TV
Enter your command->light.on
Turning on Light
Enter your command->light.off
Turning off Light
Enter your command->quit

----------------

Isn't this fun? In the next article, I will explain how I would extends the app to support JMS and SOAP command request, using Spring, stay tune.

Friday, February 09, 2007

[Tech Tips] Implementing Command Design Pattern via Spring Framework - Part 1


I been using Spring Framework for pass few months, and I am big fans of the Framework. The framework help a lot, as we don't have to write lengthly, repetitive boring code, most application code are wire via Spring XML configuration, the framework also make our code cleaner, as it provide out of box AOP engine, developer could focus on implementing module core function, and “AOPing” other programming aspects such as transaction control, logging, security, and etc when require.

Thus, to say a big thank u on providing such great framework, and contribute back to the communities, starting from today, I will use this blog to share my experience, tips, and journal of using Spring here. Most of the write up will assume u have some basic idea of using Spring (Just do a google search on Spring tutorial).

So, my very first 2007 technical topic is “Implementing Command Design Pattern using Spring”. I will use the remote control example from very popular design pattern book, “Head First Design Patterns” from OREILLY.

The original requirement of the remote control are

1 . The remote control will have multiple buttons,
2. Each button could be program to turn on/off a household device.

I change the requirement a little, the remote control will not have any buttons, but:

1. It will accept command as a string from a console
2. Each device's command will have unique command String, such as

The very first thing we need to do is to roll out the command interface


1 package blog.coolboy.springexample.cp.command;
2
3 public interface Command {
4 public CommandType getCommandType();
5 public void execute();
6 }


Next, we needs to define an enum to hold all possible supported CommandType, each CommandType holds it's command string, which is unique. That's a helper method to return CommandType base on passing command string.
 1 package blog.coolboy.springexample.cp.command;
2
3 public enum CommandType {
4 LIGHT_ON("light.on"),
5 LIGHT_OFF("light.off"),
6 TV_ON("tv.on"),
7 TV_OFF("tv.off");
8
9 private String commandString;
10
11 // return CommandType base on passing
12 // commandString
13 public static CommandType valueOfCommandString(String cmdString) {
14 CommandType theCommandType = null;
15 for(CommandType cmdType : CommandType.values()) {
16 if (cmdType.getCommandString().equals(cmdString)) {
17 theCommandType = cmdType;
18 break;
19 }
20
21 }
22 return theCommandType;
23 }
24
25 CommandType(String cmdString) {
26 commandString = cmdString;
27 }
28
29 public String getCommandString() {
30 return commandString;
31 }
32
33 public void setCommandString(String commandString) {
34 this.commandString = commandString;
35 }
36
37 }
38

Now, implements all supported commands, below is sample code TV ON Command;

 1 package blog.coolboy.springexample.cp.command.impl;
2
3 import blog.coolboy.springexample.cp.command.Command;
4 import blog.coolboy.springexample.cp.command.CommandType;
5
6
7 public class TVOnCommand implements Command {
8
9 private final static CommandType cmdType = CommandType.TV_ON;
10
11 public TVOnCommand() {
12 // U suppose to pass in a TV instance here..
13 }
14
15 public CommandType getCommandType() {
16 return this.cmdType;
17 }
18
19 public void execute() {
20 System.out.println("Switching On TV");
21 }
22
23 }

The rest of commands (TV.Off, Light On, Light.Off) follows the same structure..

In part II, we will roll out the RemoteControl class, and use Spring to inject supported commands to the Remotecontrol, and provide remoteControlService as an interactive shell for user to test out the remote control, stay tune.

Wednesday, March 22, 2006

Project All About Sudoku!

"Hi I am James, and I am addicted to Sudoku, it all started few weeks ago...".

I admit that I am very addicted to the game. I must play at least one Sudoku puzzle a day or else I feel that something is missing from me. And it's a very good brain exercise for everyone, is highly recommended for anyone who's older then 30+ and people will start calling u "uncle", like me :-(

I love the game so much that I was actually thinking of putting one Sudoku puzzle as part of the interview questions for a Java developer position which I'm hiring for my present Company. I think that if one can't even solve a simple Sudoku puzzle within a given time frame, their problem solving skill is pretty much limited. Somehow, my Manager rejected this idea.

My "Geek" friend Paul Ho and I had several interesting discussions about the game ... about algorithms on generating a unique Sudoku, what is the best program logic to solve a given puzzle ... so on. As a 120% "geek" than me and a very good Java developer, Paul was able to come out with a Java base Sudoku game under 4K and completed within 1 week time frame. Well done Paul! Bravo !

Paul 4K Sudoku game (download from here) actually triggered me to start my very first open source project called "Project all about Sudoku" hosted at sourceforge.com. The aim of this project is to provide a platform (A Java Swing Application) for developers around the world to participate by delivering various kind of plugins to make this addictive game more fun, entertaining and most importantly ... Free For All!.

Well, this project just went "live" yesterday and u can download a "SQLPlus" version of the game. Appreciate if u could check it out and do tell me what do u think. I could use all your support to boost the project ranking.