Hibernate:在没有表的情况下通过其字段加载类

时间:2016-04-09 08:11:01

标签: java hibernate jpa orm

我有一个Ink类,它有一组固定的常量。它们永远不会改变,我不想将这个类存储为表。

public final class Ink {
    public static final Ink Y = new Ink(91001, 'y', 90.70,  -5.23,  94.37), "Yellow");
    public static final Ink M = new Ink(92001, 'm', 48.19,  72.01,  -1.78), "Magenta");
    public static final Ink C = new Ink(93001, 'c', 56.46, -41.00, -43.50), "Cyan");
    public static final Ink K = new Ink(94001, 'k', 18.64,   1.80,   5.21), "Black");      

    public int code;

    public static Ink forCode(int code) {
        //...
    }

    //...
}

其他类可以包含Ink inkCollection<Ink> inks个字段,但每个ink实例必须映射为仅包含code值的简单整数列。 Code不是外键或其他东西 - 它是一个简单的整数值,我可以从中获得Ink个实例。

@Entity
public class Order {
     //...
     @OneToMany    
     public Set<Ink> inks;
     //...
}

我可以使用转换器按Ink并返回

来恢复code
@Converter(autoApply = true)
public class InkConverter implements AttributeConverter<Ink, Integer> {

     @Overrcodee
     public Integer convertToDatabaseColumn(Ink ink) {
         return ink.code;
     }

     @Overrcodee
     public Ink convertToEntityAttribute(Integer code) {
         return Ink.forCode(code);
     }
}

但问题是:

如何防止Hibernate将类映射为表格,并且仍然从其code列加载了一个类字段?

2 个答案:

答案 0 :(得分:1)

将墨水存储在Java代码中时。因此,您应该自己实施所有加载操作。首先,您可以阻止Hibernate通过注释@Transient将类映射为表。然后您可以在订单加载后处理加载操作:

public interface Inked {
    getCode();
    setInk(Ink ink);
}

public abstract class AbstractEntity {

    @PostLoad
    public void loadInk() {
        if(this instanceof Inked){
            Inked inked = (Inked) this;
            inked.setInk(Ink.forCode(getCode()));
        }
    }
}

@Entity
public class Order extends AbstractEntity implement Inked {
    //...
    public Integer code;

    @Transient
    public Ink ink;
    //...

}

答案 1 :(得分:1)

首先,您可以创建一个Enum来表示Ink实例。如果您可以更改列以存储char引用(Y,M,C,K)而不是代码,这将是最简单的解决方案。如果没有,那么您可以使用您建议的转换器从代码转换为Enum实例。

public Enum Ink {
    Y = new Ink(91001, 'y', 90.70,  -5.23,  94.37), "Yellow");
    M = new Ink(92001, 'm', 48.19,  72.01,  -1.78), "Magenta");
    C = new Ink(93001, 'c', 56.46, -41.00, -43.50), "Cyan");
    K = new Ink(94001, 'k', 18.64,   1.80,   5.21), "Black"); 

    .....     

    private static Ink (...) {
        ...
    }
}

如果您保存Y,M,C,K,映射将如下所示。如果必须保存代码,请添加必要的转换器(http://www.nurkiewicz.com/2013/06/mapping-enums-done-right-with-convert.html

@Entity
public class Order {

     @ElementCollection   
     @CollectionTable(...)
     @Enumerated(EnumType.STRING)
     public Set<Ink> inks;

     @Enumerated(EnumType.STRING)
     private Ink ink;
}