The follow statement execute error using 9i driver(Oracle JDBC Driver version - 9.0.2.0.0).
throw UncategorizedSQLException(Invalid Column Type Exception), 
errorcode: 17004.
Upgrade to Oracle JDBC Driver version - 10.2.0.1.0, it is OK.

Example:

......
PreparedStatement pst = cn.prepareStatement("select sysdate from dual where 1=?");
pst.setNull(index,  java.sql.Types.NULL);   -------- throw exception!!
......




posted @ 2007-10-09 19:39 bluoy 阅读(905) | 评论 (0)编辑 收藏

Using the JDBC 8i, 9iR1, Oracle's DATE datatype is mapped to the "java.sql.Timestamp" class. However, the new "ojdbc14.jar" driver maps DATE to "java.sql.Date", and "java.sql.Date" only holds a date (without a time), whereas "java.sql.Timestamp" holds both a date and a time.




Subject: JDBC 920x Date/TimeStamp mapping
Type: BULLETIN
Status: UNDER_EDIT
Content Type: TEXT/PLAIN
Creation Date: 29-JUL-2003
Last Revision Date: 04-OCT-2004


PURPOSE
-------
   Clarify the use of oracle.jdbc.V8Compatible property flag
 
SCOPE & APPLICATION
-------------------
JDBC 920x Date/TimeStamp mapping is different from JDBC 8i, 9iR1.
<TITLE FOR MAIN ARTICLE TEXT>
-----------------------------
Summary of  features afftected by oracle.jdbc.V8Compatible.
 
As of 9.2.0.1.0 Oracle realigned its DATE type with the java.sql.Types.DATE type.
Prior to this
java.sql.DATE and  java.sql.TIMESTAMP were mapped to java.sql.Types.TIMESTAMP.
 
This mapping change applies to JDBC default mapping (i.e when getObject() is
used for Date column.
 
example:
select sysdate from dual;
...
while (rset.next ())  {
System.out.println("getObject for sysdate  : " +
rset.getObject(1).getClass().getName());
System.out.println("getDate for sysdate :" +
rset.getDate(1).getClass().getName());
System.out.println("getTimetamp for sysdate :" +
rset.getTimestamp(1).getClass().getName());
}
 
Prior to 9201, this will return
getObject for sysdate  : java.sql.Timestamp      <<<<
getDate for sysdate :java.sql.Date
getTimetamp for sysdate :java.sql.Timestamp
 
As of 9201 onward the following will be returned
 
getObject for sysdate  : java.sql.Date        <<<<<
getDate for sysdate :java.sql.Date            >> no change
getTimetamp for sysdate :java.sql.Timestamp   >> no change
 
 
 
Note: java.sql.Date has no time portion whereas java.sql.Timestamp does.
 
 
With this change in Datatype mapping, some application will fail and/or generate
incorrect results when JDBC driver is upgraded from 8i/ 9iR1 to 920x JBDC driver.
To maintain compatibility and keep applications working after upgrade, a compatibility flag was
Provided.  Developers now have some options:
 
1>
Use oracle.jdbc.V8Compatible flag.
 
JDBC Driver does not detect database version by default.
To change the compatibility flag for handling TIMESTAMP datatypes,
connection property 'oracle.jdbc.V8Compatible' can be set to
'true' and the driver behaves as it behaved in 8i, 901x, 9200
(with respect to TIMESTAMPs).
By default the flag is set to 'false'. In OracleConnection constructor
the driver obtains the server version and set the compatibility flag
Appropriately.
 
java.util.Properties prop = new java.util.Properties ();
prop.put ("oracle.jdbc.V8Compatible", "true");
prop.put ("user", "scott");
prop.put ("password", "tiger");
String url ="jdbc:oracle:thin:@host:port:sid";
Connection conn = DriverManager.getConnection (url,prop);
 
 
 
With JDBC 10.1.0.x, in instead of the connection property, the following system
property can be useed
java -Doracle.jdbc.V8Compatible=true .....
 
 
 
Note: This flag is a client only flag that governs the Timestamp and Date mapping.
It does not affect any Database feature.
 
 
 
2> use set/getDate and set/getTimestamp   when dealing with Date and TimeStamp column datatype accordingly.
9i server  supports both Date and Timestamp column types
 
DATE is mapped to  java.sql.Date and TIMESTAMP is mapped to java.sql.Timestamp
 
I> using setTimestamp
 
PreparedStatement pstmt = conn.prepareStatement(
"SELECT count(*) from  tstable where tscol between ? and ?");
// tscol of type Timetamp (or it can be Date)
 
String s = new String("2003-01-14 10:00:00.000000000");
Timestamp ts1 = Timestamp.valueOf(s);
pstmt.setTimestamp(1, ts1); // Timestamp
 
String s2 = new String("2003-01-16 10:00:00.000000000");
Timestamp ts2 = Timestamp.valueOf(s2);
pstmt.setTimestamp(2, ts2); // Timestamp
...
 
 
II>using setDate
 
PreparedStatement pstmt = conn.prepareStatement(
"SELECT count(*) from  tstable where datecol between ? and ?");
// datecole of type Date
 
/*
pstmt.setDate(1,new java.sql.Date(System.currentTimeMillis()));
pstmt.setDate(2,new java.sql.Date(System.currentTimeMillis()));
*/
 
SimpleDateFormat start_dt_in1 = new SimpleDateFormat("2002-09-18 00:00:00");
SimpleDateFormat start_dt_in2 = new SimpleDateFormat("2003-09-18 00:00:00");
pstmt.setDate(1,start_dt_in1);
pstmt.setDate(2,start_dt_in2);
 
 
 
Summary of  features afftected by oracle.jdbc.V8Compatible.
 
Is backward compatible (with oracle.jdbc.V8Compatible)?

 
 
* Examples:
..
The following will fail   when using JDBC 9iR1, 9iR2 connecting 817 server since the
817 did not support Timestamp
 
 
Connection conn = DriverManager.getConnection(url, "scott",  "tiger");
// Prepare a statement to cleanup the emp table
Statement  stmt = conn.createStatement();
try {
stmt.execute("delete from EMP where EMPNO = 1");
} catch (SQLException e) {
}
try {
stmt.execute("INSERT INTO EMP (EMPNO, ENAME, HIREDATE) VALUES (1, 
'ALI', {ts '2003-04-14 14:19:24.94'})");
} catch (SQLException e) {
e.printStackTrace();
}
 
Error : Exception in thread "main" java.sql.SQLException: ORA-00904: invalid column name
 
Solution you need
1> fix for Bug 2640192 (included in 9204)
2> oracle.jdbc.V8Compatible", "true"
 
 
 
In earlier versions of JDBC drivers  SQL FUNCTION "TS" was mapped to "to_date" .   So, the query
 
select {ts '2002-10-18 18:02:00'} from dual;
was translated by JDBC to,
select TO_DATE ('2002-10-18 18:02:00',  'YYYY-MM-DD HH24:MI:SS') from dual;
 
 
With 9i Timestamp is supported in the database and also by 9203 JDBC Drivers.
So the query
 
select {ts '2002-10-18 18:02:00'} from dual;
 
is now translated  by JDBC to
 
select TO_TIMESTAMP('2002-10-18 18:02:00', 'YYYY-MM-DD HH24:MI:.SS.FF') from dual;
 
 
Known issues:  There is some performances issue when set/getTimestamp
Bug 3037615
Bug 2770935
These bugs are very likely duplicate.
 
 
The following code will no longer work with 9203+ unless V8 flag is set to true
 
Timestamp start_dt_in = Timestamp.valueOf("2002-09-18 00:00:00");
Timestamp now_period_start_dt ;
PreparedStatement stmt = null;
ResultSet rs = null;
 
System.out.println("start_dt_in="+  start_dt_in );
 
try {
stmt = conn.prepareStatement( "SELECT TRUNC(?) FROM DUAL" );
stmt.setTimestamp( 1, start_dt_in );
rs = (OracleResultSet) stmt.executeQuery();
if ( rs.next() ) {
now_period_start_dt = rs.getTimestamp( 1 );
System.out.println("Curr Period Start="+  now_period_start_dt );
}
 
 
will generate
Exception in thread "main" java.sql.SQLException:
ORA-932: inconsistent datatypes
 
 
Reason : trunc ( )  supports Date columns and does not support  Timestamp  (this is an RDBMS issue).
So, you need to set the V8 flag to true
 
Another bug that changed the Date/Timetamp mapping is  2428427 to comly with
J2EE 1.3 CTS.  This was fixed in 9014 and it specific to classesdmx*.zip/jar
(the *dms* jar filed mainly used by iAS/OC4J).  These *dms* jar files, by the
default value for oracle.jdbc.J2EE13Compliant  is true.  in classes111.zip
classes12.jar and ojdbc14.jar/zip the default is false.
 
One can toggel this flag  true/false by
 
java -Doracle.jdbc.J2EE13Compliant=true|false
 
 
example of of sample runs:
 
query used :"select sysdate from dual"
classes12dms.jar used.
 
 
Driver Version      Object Type
==============      ===========
9.0.1.3.0         java.sql.Timestamp >> fix for 2428427 NOT included
9.0.1.4.0         java.sql.Date   >> fix for 2428427 INCLUDED
9.0.1.5.0         java.sql.Date   >> fix for 2428427 INCLUDE
 
In JDBC 9014+ ,to keep older (9013) behavior  simply run the application with
 
 
$java -Doracle.jdbc.J2EE13Compliant=false .....
 
 
However please note that J2EE 1.3 CTS require that Date to mapped to
java.sql.Date.

posted @ 2007-10-09 19:16 bluoy 阅读(1120) | 评论 (0)编辑 收藏

我们知道,在Struts 1.0中,我们只能在web.xml中为ActionServlet指定一个配置文件,这对于我们这些网上的教学例子来说当然没什么问题,但是在实际的应用开发过程中,可能会有些麻烦。因为许多开发人员都可能同时需要修改配置文件,但是配置文件只能同时被一个人修改,这样肯定会造成一定程度上的资源争夺,势必会影响开发效率和引起开发人员的抱怨。

在Struts 1.1中,为了解决这个并行开发的问题,提出了两种解决方案:

  1. 多个配置文件的支持
  2. 模块的支持

 

支持多个配置文件,是指你能够为ActionServlet同时指定多个xml配置文件,文件之间以逗号分隔,比如Struts提供的MailReader演示例子中就采用该种方法。


            <!-- Action Servlet Configuration -->
            <servlet>
            <servlet-name>action</servlet-name>
            <servlet-class>
                org.apache.struts.action.ActionServlet
            </servlet-class> <init-param> <param-name>config</param-name> <param-value>
/WEB-INF/struts-config.xml,
/WEB-INF/struts-config-registration.xml
</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>

这种方法可以很好地解决修改冲突的问题,不同的开发人员可以在不同的配置文件中设置自己的Action、ActionForm等等(当然不是说每个开发人员都需要自己的配置文件,可以按照系统的功能模块进行划分)。但是,这里还是存在一个潜在的问题,就是可能不同的配置文件之间会产生冲突,因为在ActionServlet初始化的时候这几个文件最终还是需要合并到一起的。比如,在struts-config.xml中配置了一个名为success的<forward>,而在struts-config-registration.xml中也配置了一个同样的<forward>,那么执行起来就会产生冲突。

为了彻底解决这种冲突,Struts 1.1中引进了模块(Module)的概念。一个模块就是一个独立的子系统,你可以在其中进行任意所需的配置,同时又不必担心和其它的配置文件产生冲突。因为前面我们讲过,ActionServlet是将不同的模块信息保存在不同的ModuleConfig对象中的。要使用模块的功能,需要进行以下的准备工作:

1、为每个模块准备一个配置文件

2、配置web.xml文件,通知控制器

决定采用多个模块以后,你需要将这些信息告诉控制器,这需要在web.xml文件进行配置。下面是一个典型的多模块配置:


            <init-param>
            <param-name>config</param-name>
            <param-value>
                /WEB-INF/struts-config.xml
            </param-value> </init-param> <init-param> <param-name>config/customer</param-name> <param-value>
                /WEB-INF/struts-config-customer.xml
            </param-value> </init-param> <init-param> <param-name>config/order</param-name> <param-value>
                /WEB-INF/struts-config-order.xml
            </param-value> </init-param>

要配置多个模块,你需要在原有的一个<init-param>(在Struts 1.1中将其对应的模块称为缺省模块)的基础之上,增加模块对应的<init-param>。其中<param-name>表示为config/XXX的形式,其中XXX为对应的模块名,<param-value>中还是指定模块对应的配置文件。上面这个例子说明该应用有三个模块,分别是缺省模块、customer和order,它们分别对应不同的配置文件。

3、准备各个模块所需的ActionForm、Action和JSP等资源

但是要注意的是,模块的出现也同时带来了一个问题,即如何在不同模块间进行转发?有两种方法可以实现模块间的转发,一种就是在<forward>(全局或者本地)中定义,另外一种就是利用org.apache.struts.actions.SwitchAction。

下面就是一个全局的例子:


            ...
            <struts-config>
            ...
            <global-forwards>
            <forward name="toModuleB"
            contextRelative="true"
            path="/moduleB/index.do"
            redirect="true"/>
            ...
            </global-forwards>
            ...
            </struts-config>
            

可以看出,只需要在原有的path属性前加上模块名,同时将contextRelative属性置为true即可。此外,你也可以在<action>中定义一个类似的本地<forward>。


            <action-mappings>
            <!-- Action mapping for profile form -->
            <action path="/login"
            type="com.ncu.test.LoginAction"
            name="loginForm"
            scope="request"
            input="tile.userLogin"
            validate="true">
            <forward name="success" contextRelative="true" path="/moduleA/login.do"/>
            </action>
            </action-mappings>
            

如果你已经处在其他模块,需要转回到缺省模块,那应该类似下面这样定义,即模块名为空。


            <forward name="success" contextRelative="true" path="/login.do"/>
            

此外,你也可以使用org.apache.struts.actions.SwitchAction,例如:


            ...
            <action-mappings>
            <action path="/toModule"
            type="org.apache.struts.actions.SwitchAction"/>
            ...
            </action-mappings>
            ...
            

posted @ 2007-08-17 16:25 bluoy 阅读(190) | 评论 (0)编辑 收藏

Oracle的systimestamp的精度与OS有关。例如:
select systimestamp from dual;

基于XP的输出:07-07-03 16:07:10.328000 +08:00
基于Solaris的输出:07-07-03 16:09:18.328156 +08:00


所以,如果DB中的表以timestamp类型的字段作唯一主键的话,在PC上就会藏有隐患:主键不唯一,因为精度降低了,频繁的insert操作很有可能产生相同的主键。而在Solaris上这个可能性就很低了。

这点在DB设计中还是需要加以考虑的。

posted @ 2007-07-03 16:43 bluoy 阅读(3271) | 评论 (1)编辑 收藏

java.util.Arrays.asList的BUG

jdk 1.4对java.util.Arrays.asList的定义,函数参数是Object[]。所以,在1.4中asList()并不支持基本类型的数组作参数。

jdk 1.5中,java.util.Arrays.asList的定义,函数参数是Varargs, 采用了泛型实现。同时由于autoboxing的支持,使得可以支持对象数组以及基本类型数组。

但在使用过程中发现jdk1.5中存在一个BUG。就是等参数为基本类型的数组时,函数的行为发生了变异:它不是把这个数组转换为List,而是把这个数组整体作为返回List中的第一个元素,要取得转换后的结果,得首先get(0)才行。

到网上google了一下,Sun好像认为这并不是个问题。理由如下:
Arrays.asList is now a vararg method, and the behavior is as intended:  asList(int[] ...)
The Java generics implementation does not support non-reference type parameters.
This is all standard Java 5.0 stuff.
URL:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6353471

虽然如此,但因此函数的行为就可能产生了歧义,对调用者还是会产生误导的,我认为这终归还应该是个问题的,如能解决是最好的了。

posted @ 2007-07-03 14:55 bluoy 阅读(887) | 评论 (0)编辑 收藏

问题:同事不小心把项目DB中的一个表的数据delete all了。DB版本oracle 10g。
网上简单搜了一下,搞定。以下是过程:
Oracle 10g开始,当我执行Drop Table时,Oracle也会把被删除的表放到数据库回收站(Database Recyclebin)里。这样我们就可以用flashback table命令恢复被删除的表,语法:
   Flashback table 表名 to before drop;

开始恢复,执行以下命令:
flashback table tmm2076 TO TIMESTAMP to_timestamp('2007-05-22
12:00:00','yyyy-mm-dd hh24:mi:ss')
弹出ORA-08189错误,需要执行以下命令先:
alter table tmm2076 enable row movement

这个命令的作用是,允许oracle修改分配给行的rowid。

然后再flashback,数据被恢复完毕。

posted @ 2007-05-22 16:30 bluoy 阅读(4098) | 评论 (2)编辑 收藏

There's a field introspector written by a Velocity user in the Wiki. You can configure velocity.properties to reference this. It require velocity version 1.4.

PublicFieldUberspect.java
-------------------------------------------------------------------------------------------------------------
/*
* Copyright 2003-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.velocity.tools.generic.introspection;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import org.apache.velocity.util.introspection.Info;
import org.apache.velocity.util.introspection.UberspectImpl;
import org.apache.velocity.util.introspection.VelPropertyGet;
import org.apache.velocity.util.introspection.VelPropertySet;
/**
* Uberspect implementation that exposes public fields.
* Also exposes the explicit "length" field of arrays.
*
* <p>To use, tell Velocity to use this class for introspection
* by adding the following to your velocity.properties:<br />
*
* <code>
* runtime.introspector.uberspect = org.apache.velocity.tools.generic.introspection.PublicFieldUberspect
* </code>
* </p>
*
* @author <a href="mailto:shinobu@ieee.org">Shinobu Kawai</a>
* @version $Id: $
*/
public class PublicFieldUberspect extends UberspectImpl
{
/**
* Default constructor.
*/
public PublicFieldUberspect()
{
}
/**
* Property getter - returns VelPropertyGet appropos for #set($foo = $bar.woogie).
* <br />
* Returns a special {@link VelPropertyGet} for the <code>length</code> property of arrays.
* Otherwise tries the regular routine.  If a getter was not found,
* returns a {@link VelPropertyGet} that gets from public fields.
*
* @param obj the object
* @param identifier the name of the property
* @param i a bunch of information.
* @return a valid <code>VelPropertyGet</code>, if it was found.
* @throws Exception failed to create a valid <code>VelPropertyGet</code>.
*/
public VelPropertyGet getPropertyGet(Object obj, String identifier, Info i)
throws Exception
{
Class clazz = obj.getClass();
boolean isArray = clazz.isArray();
boolean isLength = identifier.equals("length");
if (isArray && isLength)
{
return new ArrayLengthGetter();
}
VelPropertyGet getter = super.getPropertyGet(obj, identifier, i);
// there is no clean way to see if super succeeded
// @see http://issues.apache.org/bugzilla/show_bug.cgi?id=31742
try
{
getter.getMethodName();
return getter;
}
catch (NullPointerException notFound)
{
}
Field field = obj.getClass().getField(identifier);
if (field != null)
{
return new PublicFieldGetter(field);
}
return null;
}
/**
* Property setter - returns VelPropertySet appropos for #set($foo.bar = "geir").
* <br />
* First tries the regular routine.  If a setter was not found,
* returns a {@link VelPropertySet} that sets to public fields.
*
* @param obj the object
* @param identifier the name of the property
* @param arg the value to set to the property
* @param i a bunch of information.
* @return a valid <code>VelPropertySet</code>, if it was found.
* @throws Exception failed to create a valid <code>VelPropertySet</code>.
*/
public VelPropertySet getPropertySet(Object obj, String identifier,
Object arg, Info i) throws Exception
{
VelPropertySet setter = super.getPropertySet(obj, identifier, arg, i);
if (setter != null)
{
return setter;
}
Field field = obj.getClass().getField(identifier);
if (field != null)
{
return new PublicFieldSetter(field);
}
return null;
}
/**
* Implementation of {@link VelPropertyGet} that gets from public fields.
*
* @author <a href="mailto:shinobu@ieee.org">Shinobu Kawai</a>
* @version $Id: $
*/
protected class PublicFieldGetter implements VelPropertyGet
{
/** The <code>Field</code> object representing the property. */
private Field field = null;
/**
* Constructor.
*
* @param field The <code>Field</code> object representing the property.
*/
public PublicFieldGetter(Field field)
{
this.field = field;
}
/**
* Returns the value of the public field.
*
* @param o the object
* @return the value
* @throws Exception failed to get the value from the object
*/
public Object invoke(Object o) throws Exception
{
return this.field.get(o);
}
/**
* This class is cacheable, so it returns <code>true</code>.
*
* @return <code>true</code>.
*/
public boolean isCacheable()
{
return true;
}
/**
* Returns <code>"public field getter"</code>, since there is no method.
*
* @return <code>"public field getter"</code>
*/
public String getMethodName()
{
return "public field getter";
}
}
/**
* Implementation of {@link VelPropertyGet} that gets length from arrays.
*
* @author <a href="mailto:shinobu@ieee.org">Shinobu Kawai</a>
* @version $Id: $
*/
protected class ArrayLengthGetter implements VelPropertyGet
{
/**
* Constructor.
*/
public ArrayLengthGetter()
{
}
/**
* Returns the length of the array.
*
* @param o the array
* @return the length
* @throws Exception failed to get the length from the array
*/
public Object invoke(Object o) throws Exception
{
// Thanks to Eric Fixler for this refactor.
return new Integer(Array.getLength(o));
}
/**
* This class is cacheable, so it returns <code>true</code>.
*
* @return <code>true</code>.
*/
public boolean isCacheable()
{
return true;
}
/**
* Returns <code>"array length getter"</code>, since there is no method.
*
* @return <code>"array length getter"</code>
*/
public String getMethodName()
{
return "array length getter";
}
}
/**
* Implementation of {@link VelPropertySet} that sets to public fields.
*
* @author <a href="mailto:shinobu@ieee.org">Shinobu Kawai</a>
* @version $Id: $
*/
protected class PublicFieldSetter implements VelPropertySet
{
/** The <code>Field</code> object representing the property. */
private Field field = null;
/**
* Constructor.
*
* @param field The <code>Field</code> object representing the property.
*/
public PublicFieldSetter(Field field)
{
this.field = field;
}
/**
* Sets the value to the public field.
*
* @param o the object
* @param value the value to set
* @return always <code>null</code>
* @throws Exception failed to set the value to the object
*/
public Object invoke(Object o, Object value) throws Exception
{
this.field.set(o, value);
return null;
}
/**
* This class is cacheable, so it returns <code>true</code>.
*
* @return <code>true</code>.
*/
public boolean isCacheable()
{
return true;
}
/**
* Returns <code>"public field setter"</code>, since there is no method.
*
* @return <code>"public field setter"</code>
*/
public String getMethodName()
{
return "public field setter";
}
}
}


See
http://wiki.apache.org/jakarta-velocity/PublicFieldUberspect

posted @ 2007-05-18 10:10 bluoy 阅读(272) | 评论 (0)编辑 收藏

开发要求:
为了便于维护,页面端js中的错误信息要求不能硬编码,要根据java端定义的Message对应的常量Key动态获得。

按照velocity常规做法,无法用VTL语言使用static类。调查了一下,原来velocity还是提供了变通了的实现方案的,官方论坛上还有就这一问题的争论--“Add Support for Static Utility Classes”。

 
基本上集中于两种思路:static class wrapper 和 put class into context。
前者就是作一个static class 的托管类,将托管类的实例放到context中。
1.3.1版中对应实现为org.apache.velocity.app.FieldMethodizer。
后者的想法是先把static类的Class放到context中,然后模版引擎在碰到Class对象时,优先在java.lang.Class中寻找对应的调用,然后再查找static class的调用。个人感觉这种思路比较好,用户使用比较简单直接,不需要额外的wrapper类。但官方好像更钟情于前者。计划在未来的1.6版中提供支持。

附带遇到的其他限制:
1. velocity 1.3.1版不能正常处理jdk1.5中的可变参数(Varargs) 特性。可变参数(Varargs) 其实使用对应类型的数组来实现的。velocity会因为匹配不到对应的函数原型而调用失败。其他版本未作验证。
2. velocity 1.3.1版不能正常处理jdk1.5中的enum特性。因为enum其实是按类来对待的。而velocity内部对类的处理是“取得所有的public的Methods”。所以类内部定义的enum类型的常量无法取到。这个处理请参见:org.apache.velocity.util.introspection.ClassMap。
3. velocity只能调用类/对象的methods, 无法直接使用public的attributs。原因如2。同时可以参照
Access to public member variable of a class

posted @ 2007-05-17 14:52 bluoy 阅读(2443) | 评论 (0)编辑 收藏

下面这种现象在测试阶段多次出DBoracle 10g。未作其他版本验证

test schema下共有12sequence.

其中case_seq的定义为

create sequence CASE_SEQ minvalue 1 maxvalue 99999999 start with 11531 increment by 1 cache 20;

 

用程序出的LOG如下:

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

行号 出信息

......

962 ('000000011531','000000000001','0','電話',to_date('2007/04/24

15:38','yyyy/mm/dd hh24:mi'),

......

2304 ('000000011532','000000000001','0','電話',to_date('2007/04/24

15:44','yyyy/mm/dd hh24:mi'),

......

6779 ('000000011551','000000000001','0','電話',to_date('2007/04/24

15:58','yyyy/mm/dd hh24:mi'),

......

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

 

*1 取得sequence句如下:select lpad(case_seq.nextval,12,0) as case_id from dual

*2 省略号代表其他操作,其中包含大量DB操作,包括1次其他sequence用。但无

case_seq用。

 

故障原因调查

根据象初好像和sequence_cache_entries初始化参数有

调查发现这个参数从Oracle 8.1.7后就被弃了。不知10g中是否对应参数?

 

亦或是否有其他原因造成这种现象。尚待调查。

posted @ 2007-05-09 17:10 bluoy 阅读(389) | 评论 (0)编辑 收藏

JVM‘s current path: 
   System.getProperty("user.dir");
但是JDK中使用curdir的方法并不一致,比如File.exists() VS File.getAbsolutePath().
user.dir可以通过setProperty()修改,这样就会导致上面两个函数结果相左。
不知道这是否算是JDK的一个BUG.

IDE Debug mode:
   curdir往往由所使用的IDE来决定,比如eclipse,是当前打开的project的根。
   这与程序实际运行时的curdir是不同的。在debug模式下需要考虑这一点。   

Java program runtime:
   curdir是classes或bin。
   取得方法:DummyClass.class.getResource("/").getPath();

posted @ 2007-05-08 17:23 bluoy 阅读(186) | 评论 (0)编辑 收藏

仅列出标题
共4页: 上一页 1 2 3 4 下一页