0

アプリケーションと application_descriptions 間のマッピングを持つデータベースがあります。すべてのアプリケーションは、複数の説明を持つことができます (列 product_id によってマップされます)。テーブル アプリケーションの列 product_id は重複する値を持つことができますが、列 product_id と列ラッピング_バージョンの組み合わせは一意です。したがって、説明は、最新バージョンのアプリケーションにのみマップする必要があります。

すべての説明を取得するために、テーブル アプリケーションで @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 値を試しました。

それらのいくつかは、エラーが発生したアプリケーションで機能しましたが、属性を再度削除した場合にのみ機能する他のアプリケーションでも同じエラーが発生します。何をすべきか?

私のコード(重要なゲッターとセッターのみ、より良い概要のために他のすべてを削除):

@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 の product_id の代替 a):

@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