Разработвам уеб базирано приложение, което да замени настолно базирано. Трябва да ги накарам и двамата да работят в една и съща база данни. За уеб базираното приложение използвам GWT и Hiberate (с Gilead), работещи на Tomcat 7.0. SQL сървърът е MSSQL 2000.
Получавам изключение:
com.microsoft.sqlserver.jdbc.SQLServerException: Нарушение на ограничението за PRIMARY KEY „PK_CallLog“. Не може да се вмъкне дублиран ключ в обект „CallLog“.
За да получа изключението, правя следните стъпки:
- Добавете запис на разговор със старото приложение
- Добавете запис на разговор с новото приложение (с помощта на хибернация).
Изглежда, че hibernate използва собствения си кеш и не разглежда базата данни, за да разбере какъв трябва да бъде следващият първичен ключ.
Има ли начин да принудите 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
Бих искал да избегна промяната на базата данни, доколкото е възможно, не искам да счупя по-старото приложение.