[英]Could this be a Java threading or Hibernate Issue?
我面临以下问题-无法在Performance或较低环境中重现它,但仅在Prod中使调试变得有点困难,因此,如果我能得到一些线索,请在此处发布。 试图使它尽可能短,但仍然很长。
问题 :在2个步骤的订单创建过程中,即创建客户+提交订单-我们将收到唯一约束违规,其中单个客户ID被分配给在多个位置创建的订单。
不知道哪里出了问题。 我找不到的一些东西
对于Spring / Hibernate堆栈版本,Pom Entry如下所示,数据库为Oracle
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.2.1.RELEASE</spring.version>
<hibernate.version>4.1.10.Final</hibernate.version>
<thymeleaf.version>2.1.0.RELEASE</thymeleaf.version>
<tiles.version>2.2.2</tiles.version>
</properties>
客户对象如下
@Entity
@Table(name = "CUSTOMER")
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
@SequenceGenerator(name="CUSTOMER_SEQUENCE_GENERATOR",
sequenceName="CUSTOMER_SEQ", allocationSize = 1)
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,
generator="CUSTOMER_SEQUENCE_GENERATOR")
@Column(name = "CUSTOMER_ID", unique = true, nullable = false)
private Integer id;
可以从3个控制器和2个服务方法等不同地方调用此代码段-可以在整个代码中说。
Customer customer = createCustomerEntity(newcustomer);
customer = customerManagementDAO.addUpdateCustomer(customer);
从线程的角度来看,我不确定以下代码中的某些内容是否出现错误
private Customer createCustomerEntity(CustomerBean newcustomer)
throws InternalBusinessException {
Customer customer = null;
try{
// If Loop1
if(newcustomer.getInternalcustomerid() == null){
customer = new Customer();
customer.setCustomerNumber(newcustomer.getExternalSystemCustomerid());
}
// If Loop2
if(newcustomer.getInternalcustomerid() != null){
//if a new customer going for new enrollment ,
// we lookup up the customer in DB based on
// InternalCustomerId and merge the customer.
Integer customerIdInternal = null;
// Below Call goes to Internal Database to find existing Customer
Customer customerEntity = orderManagementDAO.findExistingCustomerByCustomerId(
newcustomer.getEoecustomerid().toString());
if(customerEntity != null){
customer = new Customer();
customer.setCustomerNumber(
newcustomer.getExternalSystemCustomerid());
customerIdInternal = customerEntity.getId();
if (customerIdInternal != null) {
customer.setId(customerIdInternal);
}
}
//In case of customer look up if customer with same
// External System's id exists we merge the same customer.
// If Loop3
if(newcustomer.getExternalSystemCustomerid() != null) {
// Below call goes to external System to find existing Customer Number
Customer customerEntity = orderManagementDAO.findExistingCustomerByCustomerNumber(
newcustomer.getExternalSystemCustomerid().trim());
Integer customerIdInternal = null;
if(customerEntity != null) {
customer = new Customer();
customer.setCustomerNumber(
newcustomer.getExternalSystemCustomerid());
customerIdInternal = customerEntity.getId();
}
if (customerIdInternal != null) {
customer.setId(customerIdInternal);
}
}
// End of If loop3
customer.setEmail(newcustomer.getEmail()); //<== We have null pointers at this point in logs
customer.setFirstName(newcustomer.getFirstname());
customer.setLastName(newcustomer.getLastname());
} catch (RuntimeException e) {
throw new InternalBusinessException("createCustomerEntityForEOE failed", e);
}
return customer;
}
日志显示在具有不同线程的服务器实例中在Loop 2和Loop3中打印相同的客户ID
Null指针位于customer.setEmail的Loop3末尾
道代码如下
@SuppressWarnings("unchecked")
@Override
public Customer addUpdateCustomer(Customer customer)
throws InternalDataAccessException {
if (customer.getId() != null && customer.getId() != 0)
saveMerge(customer);
else
save(customer);
return customer;
}
如果您认为代码的其他部分可以使此问题更加清楚,请告诉我。
该问题最终更多地是业务案例方案问题,并且当整个create Customer流程移至Oracle DB中的存储产品时,该问题已解决。
我们放弃了表Cust#,以从范围中提取有效客户编号,如果消耗了它们,则执行一些步骤来设置新范围,或者增加否并执行SaveMerge()
这3个Hibernate查询步骤已更改为One Stored Proc,并且工作正常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.