0

我有一个在应用程序和 application_descriptions 之间映射的数据库。每个应用程序可以有多个描述(由列 product_id 映射)。表应用中的product_id 列可以有重复值,但是product_id 列和wrapping_version 列的组合是唯一的。所以描述应该只映射到最高版本的应用程序。

我已经在表应用程序中制定了一个 @OneToMany 映射来获取所有描述。在描述中,我只得到 product_id 的字符串。这不是最佳的,但它不能像在替代 a) 中那样映射它。

因此,我制定的解决方案可以很好地从数据库中读取数据,但是当我尝试将应用程序更新到数据库时,我得到(仅有时)以下错误:

Hibernate: 
    /* update
        com.twistbox.iwp.dao.Application */ update
            applications 
        set
            created=?,
            design_id=?,
            message=?,
            product_id=?,
            product_title=?,
            retailer_id=?,
            state=?,
            tbyb_playduration=?,
            tbyb_startups=?,
            wrapping_security_layer=?,
            wrapping_version=? 
        where
            id=?
Hibernate: 
    /* delete one-to-many com.twistbox.iwp.dao.Application.applicationDescriptions */ update
            application_descriptions 
        set
            product_id=null 
        where
            product_id=?

104330 [http-8080-1] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 1048, SQLState: 23000
104330 [http-8080-1] ERROR org.hibernate.util.JDBCExceptionReporter - Column 'product_id' cannot be null

我尝试过 1. 在更新之前将映射描述集设置为 null 2. 在更新之前设置为新的空 HashSet 对象 3. 让映射对象像我从数据库中获取一样

默认休眠不应该在更新时级联,我还没有找到停止这样做的方法(最后一次尝试是@OneToMany(cascade = {}))。我还在表中尝试了 true 和 false 值:1. 属性可以为空 2. 可更新 3. 可插入

其中一些适用于我收到错误的应用程序,但随后我收到其他应用程序的相同错误,只有当我再次删除属性时才有效。有什么想法该怎么做?

我的代码(只有重要的 getter 和 setter,所有其他的都被删除以获得更好的概览):

@Entity
@Table (name = "applications")
@FilterDef(name = "versionFilter")
public class Application implements Comparable<Application>, Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private long id;
    private Retailer retailerId;
    private long designId;
    private String productId;
    private String productTitle;
    private int tbybPlayDuration;
    private int tbybStartups;
    private int wrappingSecurityLayer;
    private int wrappingVersion;
    private ApplicationStatus status;
    private String message;
    private Timestamp created;
    private Set<ApplicationDescription> applicationDescriptions = new HashSet<ApplicationDescription>();
    private Set<PricingApplicationMapping> pricingApplication = new HashSet<PricingApplicationMapping>();


    public Application() {

    }

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @GenericGenerator(name="increment", strategy="increment")
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    @Column(name="product_id")
    public String getProductId() {
        return productId;
    }
    public void setProductId(String productId) {
        this.productId = productId;
    }


    @OneToMany(cascade = {})
    @JoinColumn(name="product_id", referencedColumnName="product_id")
    @Filter(name = "versionFilter", condition = "wrapping_version =select max(A.wrapping_version) from application A where A.product_id= product_id")
    public Set<ApplicationDescription> getApplicationDescriptions() {
        return applicationDescriptions;
    }

    public void setApplicationDescriptions(
            Set<ApplicationDescription> applicationDescriptions) {
        this.applicationDescriptions = applicationDescriptions;
    }

    @Override
    public int compareTo(Application o) {
        return this.getProductTitle().compareToIgnoreCase(o.getProductTitle());
    }

}


@Entity
@Table (name = "application_descriptions")
@FilterDef(name = "paMapping")
public class ApplicationDescription implements Comparable<ApplicationDescription>, Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private long id;
    private String productId;
//  private Application application;
//  private String countryCode;
    private Territory territory;
    private String name;
    private String description;
    private String termsAndConditions;

    public ApplicationDescription() {

    }

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @GenericGenerator(name="increment", strategy="increment")   
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }

//  @ManyToOne
//  @JoinColumn(name="product_id")
//  public Application getApplication() {
//      return application;
//  }
//
//  public void setApplication(Application application) {
//      this.application = application;
//  }

    @Column(name="product_id")
    public String getProductId() {
        return productId;
    }
    public void setProductId(String productId) {
        this.productId = productId;
    }


    @Column(name="name")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Column(name="description")
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    @Column(name="terms_and_conditions")
    public String getTermsAndConditions() {
        if (this.termsAndConditions != null && !this.termsAndConditions.equals("") && !this.termsAndConditions.toLowerCase().equals("null"))
            return this.termsAndConditions;
        return "default";
    }
    public void setTermsAndConditions(String termsAndConditions) {
        this.termsAndConditions = termsAndConditions;
    }

    @JoinColumn(name="country_code")
    @OneToOne
    public Territory getTerritory() {
        return territory;
    }

    public void setTerritory(Territory territory) {
        this.territory = territory;
    }

    @Override
    public int compareTo(ApplicationDescription o) {
        return this.getTerritory().getCountryCode().compareToIgnoreCase(o.getTerritory().getCountryCode());
    }



}

application_descriptions a) 中 product_id 的替代方案:

@ManyToOne
    @JoinColumn(name="product_id")
    public Application getApplication() {
        return application;
    }

错误信息:

Hibernate: 
    /* load one-to-many com.twistbox.iwp.dao.Application.applicationDescriptions */ select
        applicatio0_.product_id as product5_0_2_,
        applicatio0_.id as id2_,
        applicatio0_.id as id4_1_,
        applicatio0_.product_id as product5_4_1_,
        applicatio0_.description as descript2_4_1_,
        applicatio0_.name as name4_1_,
        applicatio0_.terms_and_conditions as terms4_4_1_,
        applicatio0_.country_code as country6_4_1_,
        territory1_.country_code as country1_8_0_,
        territory1_.currency as currency8_0_,
        territory1_.name as name8_0_,
        territory1_.terms_and_conditions as terms4_8_0_ 
    from
        application_descriptions applicatio0_ 
    left outer join
        territories territory1_ 
            on applicatio0_.country_code=territory1_.country_code 
    where
        applicatio0_.product_id=?

180684 [http-8080-1] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: S1009
180684 [http-8080-1] ERROR org.hibernate.util.JDBCExceptionReporter - Invalid value for getLong() - 'para'

SQL 生成表:

CREATE TABLE IF NOT EXISTS `applications` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `retailer_id` int(10) unsigned NOT NULL,
  `design_id` int(10) unsigned NOT NULL,
  `product_id` varchar(150) NOT NULL,
  `product_title` varchar(150) NOT NULL,
  `tbyb_playduration` int(10) NOT NULL,
  `tbyb_startups` int(10) NOT NULL,
  `wrapping_security_layer` int(10) unsigned NOT NULL DEFAULT '1',
  `wrapping_version` int(10) unsigned NOT NULL DEFAULT '1',
  `state` enum('WAITING','RUNNING','DONE','FAILED') NOT NULL DEFAULT 'WAITING',
  `message` varchar(250) DEFAULT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `product_id_wrapping_version` (`product_id`,`wrapping_version`),
  KEY `FK_applications_retailers` (`retailer_id`),
  KEY `FK_applications_custom_designs` (`design_id`),
  KEY `product_id` (`product_id`),
  CONSTRAINT `FK_applications_custom_designs` FOREIGN KEY (`design_id`) REFERENCES `custom_designs` (`id`),
  CONSTRAINT `FK_applications_retailers` FOREIGN KEY (`retailer_id`) REFERENCES `retailers` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



CREATE TABLE IF NOT EXISTS `application_descriptions` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `product_id` varchar(150) NOT NULL,
  `country_code` varchar(5) NOT NULL,
  `name` varchar(150) NOT NULL,
  `description` varchar(500) NOT NULL,
  `terms_and_conditions` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `product_id_county_code` (`product_id`,`country_code`),
  KEY `FK_application_descriptions_applications` (`product_id`),
  KEY `FK_application_descriptions_territories` (`country_code`),
  CONSTRAINT `FK_application_descriptions_territories` FOREIGN KEY (`country_code`) REFERENCES `territories` (`country_code`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

应用更新:

public static long updateApplication(Application application){

        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = null;
        try{
            session = sf.openSession();
            session.beginTransaction();
            session.saveOrUpdate(application);
            session.getTransaction().commit();
        }
        catch(HibernateException he){
            logger.severe("Error updating application! " + he.getMessage() + " " + he.getStackTrace());
            return -1;

        }
        catch(Exception e){
            logger.severe("Error updating application! " + e.getMessage() + " " + e.getStackTrace());
            return -1;
        }
        finally{
            session.close();
        }
        return application.getId();

    }
4

0 回答 0