我正在爲我的應用程序使用Hibernate。有時侯hibernate會生成重複的ID,我使用的策略是增量,它會從表中增加一個max(ID)。我不知道爲什麼會發生這種情況,並且突然發生,並且之後對該表插入操作的所有後續請求都失敗。解決方法是重新啓動tomact服務器。休眠會話中的持久數據變得過時,有時會通過休眠生成重複ID
這裏有應用
3應用程序部署在Liferay的-tomcat.each細節都有自己的抽象impls.jar.This JAR中包含用於使用Hibernate oracle的交互。我可以懷疑這是導致這個問題的一個可能的情況。
2.所有3個應用具有休眠相關JAR的
我已經做了以下測試,以確認是否是因爲多線程的問題,鉛, 1)創建3個線程,每個線程運行for循環20次插入同一個表>我沒有發現任何問題。一切順利。
這是上面的示例代碼。
public class ThreadTest implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<20;i++){
UserManagement userManagement = new UserManagementImpl(-1);
Context context = new Context();
context.setUserId("testUser");
context.getUserContextMap().put("password", "shiva123");
try{
int sessionId = userManagement.login(context);
System.out.println("thread<<"+Thread.currentThread().getName() + ">> "+sessionId);
}catch(Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new ThreadTest());
Thread t2 = new Thread(new ThreadTest());
Thread t3 = new Thread(new ThreadTest());
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
t1.start();
t2.start();
t3.start();
}
}
如何得到正確的ID是該問題或如何避免產生重複的ID?
這是給我的問題的代碼。
以下是hibernate映射類。
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
@javax.persistence.Entity
@Table(name="entities",
uniqueConstraints = {@UniqueConstraint(columnNames={"id"})})
@org.hibernate.annotations.GenericGenerator(
name = "test-increment-strategy",
strategy = "increment")
public class EntityImpl extends Entity {
/**
* Serial Version UID for this class
*/
private static final long serialVersionUID = -9214466697134157251L;
@Override
public String toString() {
return "EntityImpl [entityId=" + entityId + ", entityName="
+ entityName + ", entityType=" + entityType
+ ", parentEntityId=" + parentEntityId + ", entityHierarchy="
+ entityHierarchy + "]";
}
private int entityId;
private String entityName;
private String entityType;
private int parentEntityId;
private String entityHierarchy;
@Id
@GeneratedValue(generator = "test-increment-strategy")
@Column(name = "ID", nullable = false, updatable = false)
public int getEntityId() {
return entityId;
}
/** Sets the Entity ID for this instance */
public void setEntityId(int entityId) {
this.entityId = entityId;
}
/** Retrieves the name of this Entity instance */
@Column(name = "entity_name", nullable = false)
public String getEntityName() {
return entityName;
}
/** Sets the name of this Entity instance */
public void setEntityName(String entityName) {
this.entityName = entityName;
}
/** Retrieves the type of this Entity instance */
@Column(name = "entity_type", nullable = false, updatable = false)
public String getEntityType() {
return entityType;
}
/** Sets the type of this Entity instance */
public void setEntityType(String entityType) {
this.entityType = entityType;
}
/** Retrieves the Parent Entity ID for this instance */
@Column(name = "parent_id")
public int getParentEntityId() {
return parentEntityId;
}
/** Sets the Parent Entity ID for this instance */
public void setParentEntityId(int parentEntityId) {
this.parentEntityId = parentEntityId;
}
@Column(name = "ENTITY_HIERARCHY", nullable = false, updatable = false)
public String getEntityHierarchy() {
return entityHierarchy;
}
public void setEntityHierarchy(String entityHierarchy) {
this.entityHierarchy = entityHierarchy;
}
}
下面是挽救實體
private boolean save (Serializable object, Session session) throws EntityNotFoundException, InternalSystemException {
logger.debug("save() - start");
Transaction tx = null;
boolean successful = false;
boolean localInit = false;
try {
if (session == null) {
session = createSession();
tx = session.beginTransaction();
//session.save(object);
localInit = true;
}
session.save(object);
logger.debug("**********************************");
logger.debug("object: "+object);
logger.debug("**********************************");
if (localInit == true) {
tx.commit();
}
successful = true;
} catch(HibernateException ex) {
logger.error("error in saving entity "+ ex);
if (localInit == true && tx !=null)
tx.rollback();
ex.printStackTrace();
throw new InternalSystemException("error in saving entity "+ ex);
} catch(Exception ex) {
logger.error("error in saving entity "+ex);
if (localInit == true && tx !=null)
tx.rollback();
new InternalSystemException("error in saving entity "+ ex);
}finally {
if (localInit && session != null) {
session.flush();
session.clear();
session.close();
}
}
if (logger.isDebugEnabled()) {
logger.debug("save() - end");
}
return successful;
}
不會總是發生錯誤的方法,但一旦發生,同樣會繼續和測試Oracle環境是Oracle RACK。
你有3個不同的webapps,每個webapps使用增量策略插入到相同的表中嗎? –
是的.. **有3個Web應用程序和相同的JAR,並且每個插入到同一個Tablse中都被複制到每個Web應用程序的lib文件夾**。他們使用增量策略。即使我也嘗試使用序列。但問題仍然存在。 –