【问题标题】:Map null column as 0 in a legacy database (JPA)将旧数据库 (JPA) 中的空列映射为 0
【发布时间】:2011-02-28 14:15:14
【问题描述】:

使用播放!框架和它的 JPASupport 类我遇到了遗留数据库的问题。

我有以下课程:

@Entity
@Table(name="product_catalog")
public class ProductCatalog extends JPASupport {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer product_catalog;

    @OneToOne
    @JoinColumn(name="upper_catalog")
    public ProductCatalog upper_catalog;

    public String name;
}

某些产品目录没有上层目录,在旧数据库中它被引用为 0。如果我将 upper_catalog 提供为 NULL,那么 JPA 会向该数据库列插入一个 NULL 值。 写入数据库时​​如何强制 null 值为 0,而从数据库读取时如何强制 null 值为 0?

【问题讨论】:

    标签: database jpa null legacy playframework


    【解决方案1】:

    我没有看到任何直接使用 JPA 实现您想要的简单方法(而且很有可能即使您找到一种适用于保存或加载等基本操作的方法,它也不适用于更复杂的用例,如复杂标准/hql、非标准获取模式等)

    所以我会这样做:

    @Entity
    @Table(name="product_catalog")
    public class ProductCatalog extends JPASupport {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        public Integer product_catalog;
    
        @Column(name="upper_catalog")
        public Long upper_catalog_id;
    
        public String name;
    
        public ProductCatalog getUpperCatalog() {
           if (upper_catalog_id == 0)
             return null;
    
           return ProductCatalog.findById(upper_catalog_id);
        }
    
        public void setUpperCatalog(ProductCatalog pc) {
           if (pc == null) {
             upper_catalog_id = 0;
           }
           else {
             if (pc.id == null) {
                // option 1. a bit like a cascade
                pc.save();
                // option 2. if you consider passing a transient entity is not valid
                throw new RuntimeException("transient entity " + pc.toString());
             }
             upper_catalog_id = pc.id;
           }
        }
    }
    

    【讨论】:

    • 谢谢,它工作得很好!只需将 Long 更改为 Integer(一些 Play!配置?)。在这种情况下@Transient 的含义是什么 - 我没有添加它,我对这个类的所有测试似乎都通过了。
    • @Transient 被 JPA 提供者理解为:“不管理此字段(不将其保存到数据库))”。玩的时候忘记了! @Transient 仅在字段上需要。我使用 Long 因为它是默认播放!输入 id,但使用任何你想要的
    • 我刚刚重新阅读了代码,您应该小心地仅使用持久的 ProductCatalog(带有 id)调用设置器,否则它将无法工作。 (也许您应该在方法的开头添加此测试:如果 pc.id 为 null,则持久化 pc)。
    【解决方案2】:

    我看到两个选项:

    • 使用原始数据类型作为Id(即int而不是Integer
    • 如果您使用 Hibernate 作为 JPA 提供程序,请使用 CustomType 进行转换

    【讨论】:

      猜你喜欢
      • 2011-08-14
      • 2011-06-30
      • 1970-01-01
      • 2011-02-01
      • 1970-01-01
      • 2013-05-07
      • 1970-01-01
      • 1970-01-01
      • 2017-09-07
      相关资源
      最近更新 更多