TransientObjectException:给定对象具有空标识符:com.netelixir.lxr.google.entities.CampaignStructure

时间:2017-03-06 11:56:30

标签: java hibernate

当我试图更新表格时,它会显示上述异常。  我的模型类是

@Entity
@com.googlecode.objectify.annotation.Entity
@Table(name = "campaign_structure")
@CsvReport(value = ReportDefinitionReportType.CAMPAIGN_PERFORMANCE_REPORT)
public class CampaignStructure extends Report implements Serializable{

  @Column(name = "CAMPAIGN_ID")
  @CsvField(value = "Campaign ID", reportField = "CampaignId")
  private Long campaignId;

  @Column(name = "CAMPAIGN_NAME", length = 255)
  @CsvField(value = "Campaign", reportField = "CampaignName")
  private String campaignName;

  @Column(name = "CAMPAIGN_STATUS", length = 32)
  @CsvField(value = "Campaign state", reportField = "CampaignStatus")
  private String campaignStatus;

  @Column(name = "BUDGET")
  @CsvField(value = "Budget", reportField = "Amount")
  @MoneyField
  private BigDecimal budget;

  @Column(name = "BUDGET_ID")
  @CsvField(value = "Budget ID", reportField = "BudgetId")
  private Long budgetId;

  @Lob
  @Column(name = "LABELS", length = 2048)
  @CsvField(value = "Labels", reportField = "Labels")
  private String labels;
  @Lob
  @Column(name = "LABEL_IDS", length = 2048)
  @CsvField(value = "Label IDs", reportField = "LabelIds")
  private String labelIds;


  @Column(name = "ADVERTISING_CHANNEL_TYPE", length = 32)
  @CsvField(value = "Advertising Channel", reportField = "AdvertisingChannelType")
  protected String advertisingChannelType;

  @Column(name = "ADVERTISING_CHANNEL_SUBTYPE", length = 32)
  @CsvField(value = "Advertising Sub Channel", reportField = "AdvertisingChannelSubType")
  protected String advertisingChannelSubType;


  @Column(name = "TRACKING_URL_TEMPLATE", length=2048)
  @CsvField(value = "Tracking template", reportField = "TrackingUrlTemplate")
  private String trackingUrlTemplate;

  @Column(name = "URL_CUSTOM_PARAMETERS", length=2048)
  @CsvField(value = "Custom parameter", reportField = "UrlCustomParameters")
  private String urlCustomParameters;

  @Column(name = "START_DATE", length=2048)
  @CsvField(value = "Start date", reportField = "StartDate")
  @Temporal(javax.persistence.TemporalType.DATE)
  private Date startDate;

  @Column(name = "END_DATE", length=2048)
  @CsvField(value = "End date", reportField = "EndDate")
  @Temporal(javax.persistence.TemporalType.DATE)

我的Dao班[更新一号]

    public void updateCampaign(Campaign campaigns,GleServices gleServices){
              Session session = sessionFactory.openSession();
          Transaction tx = null;
          try{
          session = sessionFactory.openSession();
          StringBuilder updateStmt = new StringBuilder();
updateStmt.append(" update CampaignStructure ");
updateStmt.append(" set accountId = :accountId ");
updateStmt.append(" , budget = :budget ");
updateStmt.append(" , campaignName= :campaignName ");
updateStmt.append(", budgetId = :budgetId");
updateStmt.append(", campaignStatus = :campaignStatus");
updateStmt.append(", startDate = :startDate");
updateStmt.append(", endDate = :endDate");
updateStmt.append(", trackingUrlTemplate = :trackingUrlTemplate");
updateStmt.append(", urlCustomParameters = :urlCustomParameters");
updateStmt.append(", labels = :labels");
updateStmt.append(" where campaignId = :campaignId");
Query query = session.createQuery(updateStmt.toString());
query.setParameter("accountId", gleServices.getAccountDetails().getSeAccountId());
query.setParameter("budget", BigDecimal.valueOf((campaigns.getBudget().getAmount().getMicroAmount())));
query.setParameter("campaignId", campaigns.getId());
query.setParameter("campaignName", campaigns.getName());
query.setParameter("budgetId", campaigns.getBudget().getBudgetId());
query.setParameter("campaignStatus", campaigns.getStatus());
query.setParameter("startDate", campaigns.getStartDate());
query.setParameter("endDate", campaigns.getEndDate());
query.setParameter("trackingUrlTemplate", campaigns.getTrackingUrlTemplate());
if(campaigns.getUrlCustomParameters() != null){
                      query.setParameter("urlCustomParameters",getUrlCustomParams(campaigns.getUrlCustomParameters().getParameters()));  
                    }else{
                      query.setParameter("urlCustomParameters",null);    
                    }
 if(campaigns.getLabels()!=null){
//        campaignStructure.setLabels(campaigns.getLabels().toString());
        query.setParameter("labels", campaigns.getLabels().toString());
        }
        else
        query.setParameter("labels", null);
query.executeUpdate();
          }catch (HibernateException e) {
             if (tx!=null) tx.rollback();
             e.printStackTrace(); 
          }finally {
             session.close(); 
          }        

        }

在广告系列变量中我们获取所有数据,从广告系列我需要将所有数据更新为(campaign_structure)表

1 个答案:

答案 0 :(得分:0)

您正在尝试更新实体而不事先将其加载到persistenece上下文中。

你非常接近,如果你只是取消注释:

CampaignStructure campaignStructure = 
   (CampaignStructure) session.load(CampaignStructure.class, Long.valueOf(campaigns.getId()));

此外,您需要将@Id注释添加到实体中的campaignId字段,以便让持久性提供程序知道它应该查询实体的字段。

<强>更新

如果您无法更改实体签名,则必须使用批量更新功能。你可以这样做:

StringBuilder updateStmt = new StringBuilder();
updateStmt.append("update CampaignStructure ");
updateStmt.append("set accountId = :accountId ");
updateStmt.append(", budget = :budget");
...
updateStmt.append(" where campaignId = :campaignId");

然后创建一个查询并更新参数:

Query query = session.createQuery(updateStmt.toString());
query.setParameter("accountId", accountId);
query.setParameter("budget", budget);
...
query.setParameter("campaignId", campaignId);

最后执行:

query.executeUpdate();

批量更新/删除是一般的最后手段,这肯定是一种解决方法..但如果您无法更改实体签名,那么如果您想使用HQL,则可以使用此解决方案。