我正在开发一个基于 Web 的应用程序来替换基于桌面的应用程序。我需要让它们都在同一个数据库上工作。对于基于 Web 的应用程序,我使用 GWT 和 Hiberate(与 Gilead),在 Tomcat 7.0 上运行。SQL 服务器是 MSSQL 2000。
我得到了例外:
com.microsoft.sqlserver.jdbc.SQLServerException:违反主键约束“PK_CallLog”。无法在对象“CallLog”中插入重复键。
要获得异常,我执行以下步骤:
- 使用旧应用程序添加通话记录
- 使用新应用程序添加通话记录(使用休眠)。
似乎hibernate正在使用自己的缓存,而不是查看数据库来确定下一个主键应该是什么。
有没有办法通过查看数据库来强制休眠获取下一个密钥?
这是通话记录的映射:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hib.....dtd">
<hibernate-mapping>
<class name="com.asi.shared.Call" table="CallLog">
<id name="id" column="callid">
<generator class="increment"/>
</id>
<property name="caller"/>
<property name="callDate" column="calldate"/>
.... other props ....
<property name="checkOut" column="checkout"/>
<many-to-one name="customer" class="com.asi.shared.Customer"
column="customerid" not-found="ignore"/>
</class>
</hibernate-mapping>
这是我用来添加新调用的方法:
public Integer saveCall(Call call){
DebugLog.print("HelpDeskServiceImpl.saveCall(call)");
Session session = gileadHibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
check(session);
session.saveOrUpdate(call);
session.getTransaction().commit();
return call.getId();
}
通话记录的架构:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[CallLog]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[CallLog]
GO
CREATE TABLE [dbo].[CallLog] (
[callid] [int] NOT NULL ,
[caller] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[calldate] [datetime] NULL ,
.... other columns ....
[checkout] [varchar] (5) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
我想尽可能避免更改数据库,我不想破坏旧的应用程序。