#
錯誤提示:
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not fetch initial value for increment generator
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.id.IncrementGenerator.getNext(IncrementGenerator.java:107)
at org.hibernate.id.IncrementGenerator.generate(IncrementGenerator.java:44)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:91)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:530)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:518)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:514)
at hibernatedao.Myuser2DAO.save(Myuser2DAO.java:28)
at HibernateDaoTest.main(HibernateDaoTest.java:24)
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 對象名 user' 無效。
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(Unknown Source)
hbm.xml代碼:
<hibernate-mapping>
<class name="hibernatedao.Myuser2" table="t_myuser2" schema="dbo" catalog="myssh">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="increment" />
</id>
<property name="username" type="java.lang.String">
<column name="username" length="50" not-null="true" />
</property>
<property name="password" type="java.lang.String">
<column name="password" length="50" not-null="true" />
</property>
</class>
</hibernate-mapping>
錯誤原因一:
要將 <generator class="increment"> </generator>中的"increment"換成"native".
將主鍵的生成交給數據庫來維護。
原因二:對象名不能為“user"
原因三:在SQLServer企業管理器,選中表格,編輯
在底部有一個[標識],選中是
Java入門--漫談Java程序的性能優化
2008-03-14 11:06 作者:shenkai 來源:賽迪網
[摘要] 在java中,使用最頻繁、同時也是濫用最多的一個類或許就是java.lang.String,它也是導致代碼性能低下最主要的原因之一。
[關鍵字]
Java 程序 性能優化
Java使得復雜應用的開發變得相對簡單。毫無疑問,它的這種易用性對Java的大范圍流行功不可沒。然而,這種易用性實際上是一把雙刃劍。一個設計良好的Java程序,性能表現往往不如一個同樣設計良好的C++程序。在Java程序中,性能問題的大部分原因并不在于Java語言,而是在于程序本身。養成好的代碼編寫習慣非常重要,比如正確地、巧妙地運用java.lang.String類和java.util.Vector類,它能夠顯著地提高程序的性能。下面我們就來具體地分析一下這方面的問題。
在java中,使用最頻繁、同時也是濫用最多的一個類或許就是java.lang.String,它也是導致代碼性能低下最主要的原因之一。請考慮下面這個例子:
String s1 = "Testing String";
String s2 = "Concatenation Performance";
String s3 = s1 + " " + s2;
幾乎所有的Java程序員都知道上面的代碼效率不高。那么,我們應該怎么辦呢?也許可以試試下面這種代碼:
StringBuffer s = new StringBuffer();
s.append("Testing String");
s.append(" ");
s.append("Concatenation Performance");
String s3 = s.toString();
這些代碼會比第一個代碼片段效率更高嗎?答案是否定的。這里的代碼實際上正是編譯器編譯第一個代碼片段之后的結果。既然與使用多個獨立的String對象相比,StringBuffer并沒有使代碼有任何效率上的提高,那為什么有那么多的Java書籍批評第一種方法、推薦使用第二種方法?
第二個代碼片段用到了StringBuffer類(編譯器在第一個片段中也將使用StringBuffer類),我們來分析一下StringBuffer類的默認構造函數,下面是它的代碼:
public StringBuffer() { this(16); }
默認構造函數預設了16個字符的緩存容量?,F在我們再來看看StringBuffer類的append()方法:
public synchronized StringBuffer append(String str) {
if (str == null) {
str = String.valueOf(str);
}
int len = str.length();
int newcount = count + len;
if (newcount > value.length) expandCapacity(newcount);
str.getChars(0, len, value, count);
count = newcount; return this;
}
append()方法首先計算字符串追加完成后的總長度,如果這個總長度大于StringBuffer的存儲能力,append()方法調用私有的expandCapacity()方法。expandCapacity()方法在每次被調用時使StringBuffer存儲能力加倍,并把現有的字符數組內容復制到新的存儲空間。
在第二個代碼片段中(以及在第一個代碼片段的編譯結果中),由于字符串追加操作的最后結果是“Testing String Concatenation Performance”,它有40個字符,StringBuffer的存儲能力必須擴展兩次,從而導致了兩次代價昂貴的復制操作。因此,我們至少有一點可以做得比編譯器更好,這就是分配一個初始存儲容量大于或者等于40個字符的StringBuffer,如下所示:
StringBuffer s = new StringBuffer(45);
s.append("Testing String");
s.append(" ");
s.append("Concatenation Performance");
String s3 = s.toString();
再考慮下面這個例子:
String s = "";
int sum = 0;
for(int I=1; I<10; I++) {
sum += I;
s = s + "+" +I ;
}
s = s + "=" + sum;
分析一下為何前面的代碼比下面的代碼效率低:
StringBuffer sb = new StringBuffer();
int sum = 0;
for(int I=1;
I<10; I++){
sum + = I;
sb.append(I).append("+");
}
String s = sb.append("=").append(sum).toString();
原因就在于每個s = s + "+" + I操作都要創建并拆除一個StringBuffer對象以及一個String對象。這完全是一種浪費,而在第二個例子中我們避免了這種情況。
我們再來看看另外一個常用的Java類??java.util.Vector。簡單地說,一個Vector就是一個java.lang.Object實例的數組。Vector與數組相似,它的元素可以通過整數形式的索引訪問。但是,Vector類型的對象在創建之后,對象的大小能夠根據元素的增加或者刪除而擴展、縮小。請考慮下面這個向Vector加入元素的例子:
Object obj = new Object();
Vector v = new Vector(100000);
for(int I=0;
I<100000; I++) { v.add(0,obj); }
除非有絕對充足的理由要求每次都把新元素插入到Vector的前面,否則上面的代碼對性能不利。在默認構造函數中,Vector的初始存儲能力是10個元素,如果新元素加入時存儲能力不足,則以后存儲能力每次加倍。Vector類就象StringBuffer類一樣,每次擴展存儲能力時,所有現有的元素都要復制到新的存儲空間之中。下面的代碼片段要比前面的例子快幾個數量級:
Object obj = new Object();
Vector v = new Vector(100000);
for(int I=0; I<100000; I++) { v.add(obj); }
同樣的規則也適用于Vector類的remove()方法。由于Vector中各個元素之間不能含有“空隙”,刪除除最后一個元素之外的任意其他元素都導致被刪除元素之后的元素向前移動。也就是說,從Vector刪除最后一個元素要比刪除第一個元素“開銷”低好幾倍。
假設要從前面的Vector刪除所有元素,我們可以使用這種代碼:
for(int I=0; I<100000; I++){ v.remove(0); }
但是,與下面的代碼相比,前面的代碼要慢幾個數量級:
for(int I=0; I<100000; I++){ v.remove(v.size()-1); }
從Vector類型的對象v刪除所有元素的最好方法是:
v.removeAllElements();
假設Vector類型的對象v包含字符串“Hello”。考慮下面的代碼,它要從這個Vector中刪除“Hello”字符串:
String s = "Hello"; int i = v.indexOf(s); if(I != -1) v.remove(s);
這些代碼看起來沒什么錯誤,但它同樣對性能不利。在這段代碼中,indexOf()方法對v進行順序搜索尋找字符串“Hello”,remove(s)方法也要進行同樣的順序搜索。改進之后的版本是:
String s = "Hello"; int i = v.indexOf(s); if(I != -1) v.remove(i);
這個版本中我們直接在remove()方法中給出待刪除元素的精確索引位置,從而避免了第二次搜索。一個更好的版本是:
String s = "Hello"; v.remove(s);
最后,我們再來看一個有關Vector類的代碼片段:
for(int I=0; I
如果v包含100,000個元素,這個代碼片段將調用v.size()方法100,000次。雖然size方法是一個簡單的方法,但它仍舊需要一次方法調用的開銷,至少JVM需要為它配置以及清除堆棧環境。在這里,for循環內部的代碼不會以任何方式修改Vector類型對象v的大小,因此上面的代碼最好改寫成下面這種形式:
int size = v.size(); for(int I=0; I
雖然這是一個簡單的改動,但它仍舊贏得了性能。畢竟,每一個CPU周期都是寶貴的。
拙劣的代碼編寫方式導致代碼性能下降。但是,正如本文例子所顯示的,我們只要采取一些簡單的措施就能夠顯著地改善代碼性能。
1.如果沒有線程同步,最好習慣用StringWriter而不是StringBuffer,因為,StringBuffer是線程安全的,所以,效率會稍微低一點.
當然JDK5以后,還提供了StringBulder,這個類要比StringWriter更好用一些,當然也不是線程安全的.
如果要用StringBuffer,請盡量使用append,不要用+,在用StringBuffer時盡量先分配空間如:StringBuffer s = new StringBuffer(45);
2.數據庫查詢的結果集處理,我們對數據庫操作時,可能會針對里面的數據做處理性質的遷移.一般都是先Select一把,然后把結果集的內容處理,
最后Insert或Update回數據庫.這個是效率最低下的.無論是否使用Hibernate都很低下.當然,最好是寫一個存儲過程來完成這件事,
我們只是調用一下,觸發這個事件就可以了.如果非要自己寫程序完成,
那么,一定要注意,你在Select的時候,不要將所有數據一次性全都查詢出來,
要按行數分次處理否則很容易將內存暴掉.因為,這些數據即使你已經處理完了,
但是,對象有可能被Map或者Collection的某個對象所引用,這樣JVM就無法進行回收.
3.程序慢,要找到瓶頸在哪里,這樣才能解決.一般是三大部分,一個CPU占用率過高;一個是硬盤訪問過于頻繁;一個是網絡擁塞.
a.CPU占用又可以分三個部分,一個是tomcat占用過高;一個是數據庫占用過高;另一個是其他程序(如遠程控制程序)占用過高...tomcat過高,
最有可能是處理數據算法效率太低.數據庫占用過高,最有可能的是頻繁對一個已經很長的表進行了操作(可以通過建臨時表來進行緩解,效果不錯).
其他程序想辦法不使用這些程序或再找個空閑的服務器來run這些程序.
b.一般硬盤訪問頻繁,CPU是不會過高的.比如有一個循環程序,因數據不合要求總是打印日志,而日志就寫在文件里,
這樣,由于寫日志文件而使得處理線程進展緩慢.可以通過對數據進行預處理,來緩解硬盤訪問頻繁的狀況,或者根據特點采用緩沖區,多線程寫文件等技術來解決這樣的問題.
c.網絡擁塞,看看是否有網絡攻擊(DOS或者ARP之類的),或者增加帶寬.如果是由于聯通和電信的互訪造成慢的,那么可以考慮使用鐵通之類的節點進行中轉,效果還算可以.
可以利用觸發器同步,在觸發器中通過系統表獲取數據庫中的表、視圖等對象,然后同步。
觸發器同步參照:
- SQL code
- --====================================================
--發布/訂閱的效果最好.
--自己寫觸發器同步的實時性和可控制性最好.
--====================================================
如果只是簡單的數據同步,可以用觸發器來實現.下面是例子:
--測試環境:SQL2000,遠程主機名:xz,用戶名:sa,密碼:無,數據庫名:test
--創建測試表,不能用標識列做主鍵,因為不能進行正常更新
--在本機上創建測試表,遠程主機上也要做同樣的建表操作,只是不寫觸發器
if exists (select * from dbo.sysobjects where id = object_id(N'[test]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [test]
create table test(id int not null constraint PK_test primary key
,name varchar(10))
go
--創建同步的觸發器
create trigger t_test on test
for insert,update,delete
as
set XACT_ABORT on
--啟動遠程服務器的MSDTC服務
exec master..xp_cmdshell 'isql /S"xz" /U"sa" /P"" /q"exec master..xp_cmdshell ''net start msdtc'',no_output"',no_output
--啟動本機的MSDTC服務
exec master..xp_cmdshell 'net start msdtc',no_output
--進行分布事務處理,如果表用標識列做主鍵,用下面的方法
BEGIN DISTRIBUTED TRANSACTION
delete from openrowset('sqloledb','xz';'sa';'',test.dbo.test)
where id in(select id from deleted)
insert into openrowset('sqloledb','xz';'sa';'',test.dbo.test)
select * from inserted
commit tran
go
--插入數據測試
insert into test
select 1,'aa'
union all select 2,'bb'
union all select 3,'c'
union all select 4,'dd'
union all select 5,'ab'
union all select 6,'bc'
union all
-
JBoss內存溢出處理 原文來自:http://jboss.cn/read.php?tid=250
前幾天公司一個項目的服務器壞了,就換了一個備份服務器頂替一下,但是沒有跑一會就宕機了,一直報java.lang.OutOfMemoryError。。。。一看到這里,就知道是內存溢出,但是JBoss的內存配置已經達到1024M了,而且對JBoss內存的監測結果看,并不高,怎么會死機呢,好奇怪。搞了半天還是沒有結果。郁悶~~~~
到了最后,已經絕望了我,打算換一個JBoss版本,再換一個JDK,看看是不是這些的問題。但是再換以前,我就把日志又重新看了一次,發現一個問題。報的java.lang.OutOfMemoryError后面還有內容:java.lang.OutOfMemoryError: PermGen space,這個好像和java.lang.OutOfMemoryError: Java heap space這個不一樣。最后找了一下這個異常!
PermGen space的全稱是Permanent Generation space,是指內存的永久保存區域。這一部分用于存放Class和Meta的信息,Class在被 Load的時候被放入PermGen space區域,它和和存放Instance的Heap區域不同,GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,所以如果你的APP會LOAD很多CLASS的話,就很可能出現PermGen space錯誤。這種錯誤常見在web服務器對JSP進行pre compile的時候。
改正方法,在 run.bat 中加入:-Xms512m -Xmx1024m -XX:MaxNewSize=256m -XX:MaxPermSize=256m
因為項目中引用了很多的 jar 包,而這些 jar 包中的 class 信息會被 JBoss 的 class loader 加載到 PermGen space 區域,在 JVM 默認的情況下,該部分空間的大小只有 4M,在 jar 包非常多的情況下,顯然是不夠用的,所以通過 -XX:MaxPermSize=256m 指定最大值后即可解決問題。
我的JBoss里面裝載了6個應用,jar包和class加起來有100m左右,配上這個參數后,一切OK,最后服務器修好以后,發現,這個里面的JBoss也是這么來配置的,哎~~看來以后備份,最好還是吧JBoss一起備份出來吧!
而當出現出現 java.lang.OutOfMemoryError: Java heap space 這個異常時,通過調節-Xms512m -Xmx1024m這個就可以解決。
另外,這個兩個參數 -XX:+UseParallelGC -XX:+UseParallelOldGC 讓服務并行回收內存空間。但是,這兩個參數配置上去以后,也會占用一定的內存空間。
import java.io.FileInputStream;
public class ParseClassFile {
public static void main(String args[]) {
try {
// 讀取文件數據,文件是當前目錄下的First.class
FileInputStream fis = new FileInputStream("e:/logout_jsp.class");
int length = fis.available();
// 文件數據
byte[] data = new byte[length];
// 讀取文件到字節數組
fis.read(data);
// 關閉文件
fis.close();
// 解析文件數據
parseFile(data);
} catch (Exception e) {
System.out.println(e);
}
}
private static void parseFile(byte[] data) {
// 輸出魔數
System.out.print("魔數(magic):0x");
System.out.print(Integer.toHexString(data[0]).substring(6)
.toUpperCase());
System.out.print(Integer.toHexString(data[1]).substring(6)
.toUpperCase());
System.out.print(Integer.toHexString(data[2]).substring(6)
.toUpperCase());
System.out.println(Integer.toHexString(data[3]).substring(6)
.toUpperCase());
// 主版本號和次版本號碼
int minor_version = (((int) data[4]) << 8) + data[5];
int major_version = (((int) data[6]) << 8) + data[7];
System.out.println("版本號(version):" + major_version + "."
+ minor_version);
}
}
運行:
E:\>javac ParseClassFile.java
E:\>java ParseClassFile
魔數(magic):0xCAFEBABE
版本號(version):48.0
48代表JDK1.5.0
believe it or not
信不信由你!
it's very hot these days in bingjing
這些天非常熱
that means i am not eautiful enough to impress you.
這意味著我不美麗足以打動你!
I am so disappointed
我非常失望!
it seem to some star
看起來好像明星
it is me!!no doubt otherwise i'll be angry
這是我,毫無疑問,否則我會生氣!
you are leaving?
你要離開?
I'm scared~
我怕
all right, everyone,I should out duty now
我要下班了!各位
maybe he is gone
也許他走了
playboy,don't hidden yourself,
花花公子,不要隱藏自己!
sorry,just now ,my boss called me!
報qian,剛剛老板叫我!
i working
我正在工作。
do you often chat online?
你經常在線聊天嗎?
hi,long time no see! still remember me?
很長時間不見,大家還記得我嗎?
i nearly forget you,sorry
對不起,差點把你給忘了!
Kevin is so thin, be a man, you should eat as much as you can from now on.
凱文是瘦了很多,做一個男人,你應該吃了,您可以從現在開始。
I am waiting for my fast food
我在等我的快餐。
so, beauty, why dont you post your pic and feast our eyes? hehe
因此,如此漂亮,為什么不讓我們看看你的相片,讓我們一抱眼福
color wolf
色狼
take a nap~
小睡一會
i was a little busy just now
現在我有點忙!
every administrator should think twice about it
每個管理員應該要三思而后行
would be done soon
很快就完了
i have never ever been to there
我從來沒去過那!
--壓縮日志及數據庫文件大小 ?
? ?
? 1.清空日志 ?
? DUMP ? ? TRANSACTION ? ? 庫名 ? ? WITH ? ? NO_LOG ? ? ? ? ?
? ?
? 2.截斷事務日志: ?
? BACKUP ? LOG ? 數據庫名 ? WITH ? NO_LOG ?
? ?
? 3.收縮數據庫文件(如果不壓縮,數據庫的文件不會減小 ?
? 企業管理器--右鍵你要壓縮的數據庫--所有任務--收縮數據庫--收縮文件 ?
? --選擇日志文件--在收縮方式里選擇收縮至XXM,這里會給出一個允許收縮到的最小M數,直接輸入這個數,確定就可以了 ?
? --選擇數據文件--在收縮方式里選擇收縮至XXM,這里會給出一個允許收縮到的最小M數,直接輸入這個數,確定就可以了 ?
? ?
? 也可以用SQL語句來完成 ?
? --收縮數據庫 ?
? DBCC ? SHRINKDATABASE(客戶資料) ?
? ?
? --收縮指定數據文件,1是文件號,可以通過這個語句查詢到:select ? * ? from ? sysfiles ?
? DBCC ? SHRINKFILE(1) ?
? ?
? 4.為了最大化的縮小日志文件 ?
? a.分離數據庫: ?
? 企業管理器--服務器--數據庫--右鍵--分離數據庫 ?
? ?
? b.在我的電腦中刪除LOG文件 ?
? ?
? c.附加數據庫: ?
? 企業管理器--服務器--數據庫--右鍵--附加數據庫 ?
? ?
? 此法將生成新的LOG,大小只有500多K ?
? ?
? 或用代碼: ? ?
? 下面的示例分離 ? pubs,然后將 ? pubs ? 中的一個文件附加到當前服務器。 ?
? ?
? a.分離 ?
? EXEC ? sp_detach_db ? @dbname ? = ? 'pubs' ?
? ?
? b.刪除日志文件 ?
? ?
? c.再附加 ?
? EXEC ? sp_attach_single_file_db ? @dbname ? = ? 'pubs', ? ?
? ? ? ? @physname ? = ? 'c:\Program ? Files\Microsoft ? SQL ? Server\MSSQL\Data\pubs.mdf' ?
? ?
? 5.為了以后能自動收縮,做如下設置: ?
? 企業管理器--服務器--右鍵數據庫--屬性--選項--選擇"自動收縮" ?
? ?
? --SQL語句設置方式: ?
? EXEC ? sp_dboption ? '數據庫名', ? 'autoshrink', ? 'TRUE' ?
? ?
? 6.如果想以后不讓它日志增長得太大 ?
? 企業管理器--服務器--右鍵數據庫--屬性--事務日志 ?
? --將文件增長限制為xM(x是你允許的最大數據文件大小) ?
? ?
? --SQL語句的設置方式: ?
? alter ? database ? 數據庫名 ? modify ? file(name=邏輯文件名,maxsize=20)??
清空.ldf大?。?br />
backup?log?database with?NO_LOG
backup?log?database with?TRUNCATE_ONLY
DBCC?SHRINKDATABASE(database )?查詢日志大小:
dbcc sqlperf(logspace)
DOS命令關閉JBOSS窗口。
E:\jboss-3.2.5\bin\shutdown.bat --
如果JBOSS窗口仍存在,查看run.bat中
:END
if "%NOPAUSE%" == "" pause
:END_NO_PAUSE
如果有以上這句,那么就得去掉 if "%NOPAUSE%" == "" pause 相當于去掉pause命行。
再試試,一切OK了!
http://www.suneca.com/article.asp?id=31
覺得寫得不錯。鏈接地址先!
出現錯誤:
javax.naming.NoInitialContextException: Cannot instantiate class: org.jnp.interfaces.NamingContextFactory. Root exception is java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:198)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:186)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:265)
at java.lang.ClassLoader.loadClass(ClassLoader.java:262)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:322)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:207)
at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:42)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:649)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:243)
at javax.naming.InitialContext.init(InitialContext.java:219)
at javax.naming.InitialContext.<init>(InitialContext.java:195)
at zizz.ejb.client.UserServiceClient.main(UserServiceClient.java:38)
原因:包沒有加載,直接在classpath里加上,或在eclipse工具里build path