java - 持久映射<实体,双> : having BLOB instead of String key in join table

标签 java jpa derby

我正在开发卡路里计算器。我有实体 Dish (由配料或其他菜肴组成的可食用元素)和Ingredient (原子可食用,例如“土 bean ”的“水”)。两者都扩展类 AbstractEdible实现接口(interface) Edible .

Dish包含字段 recipe类型 Map<Edible, Double> , 其中Double代表每个“菜肴元素”(配料或其他菜肴)的重量。

我正在尝试使用 JPA 和 Derby 保留所有这些内容。我希望有一个包含以下字段的连接表:

  1. 菜实体的Key
  2. DOUBLE表示“菜元素”重量的值
  3. “dish 元素”实体的键

这是我的真实情况:

enter image description here

而不是 VARCHAR “盘子元素”实体的键我有一个 BLOB我不知道为什么。因此,我在更新现有 Dish 时遇到问题(获取 ERROR 42818: Comparisons between 'BLOB' and 'BLOB' are not supported )。非常感谢您的帮助!

菜肴

package com.singularityfx.kcalibri2.model.edibles;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.MapKeyJoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Transient;
import javax.persistence.JoinColumn;

@Entity
public class Dish extends AbstractEdible implements EdiblesCollection {
    @Transient
    private static final long serialVersionUID = -5646610412222252829L;

    @ElementCollection
    @CollectionTable(name="dish_recipe")
    @Column(name="weight")
    @MapKeyJoinColumn(name="ingredient_or_dish", referencedColumnName="name")
    private Map<Edible, Double> recipe = new HashMap<Edible, Double>();

    @Transient
    private KCalculator kCalculator = new KCalculator();

    public Dish() {}

    public Dish(String name, DishCategory category) {
        this.name = name;
        this.category = category;
    }

    @Override
    public double getKCalNonDessert() {
        kCalculator.init(recipe);
        return kCalculator.getkCalNonDessertPer100g();
    }

    @Override
    public double getKCalDessert() {
        kCalculator.init(recipe);
        return kCalculator.getkCalDessertPer100g();
    }

    @Override
    public double getKCal() {
        kCalculator.init(recipe);
        return kCalculator.getkCalPer100g();
    }

    @Override
    public double getKCalDessertTotal() {
        kCalculator.init(recipe);
        return kCalculator.getTotalKCalDessert();
    }

    @Override
    public double getKCalNonDessertTotal() {
        kCalculator.init(recipe);
        return kCalculator.getTotalKCalNonDessert();
    }

    @Override
    public double getKCalTotal() {
        kCalculator.init(recipe);
        return kCalculator.getTotalKCal();
    }

    public Double addIngredient(Edible edible, Double weight) {
        return recipe.put(edible, weight);
    }

    public Double removeIngredient(Edible edible) {
        return recipe.remove(edible);
    }

    @Override
    public Map<Edible, Double> getContent() {
        return recipe;
    }

    @Override
    public void setContent(Map<Edible, Double> content) {
        this.recipe = content;
    }

    @Override
    public void clearContent() {
        this.recipe.clear();
    }

    public double getWeight(Edible edible) {
        return recipe.get(edible);
    }

    public Collection<Edible> getEdibles() {
        return recipe.keySet();
    }

}

成分

package com.singularityfx.kcalibri2.model.edibles;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.NamedQuery;
import javax.persistence.Transient;

@Entity
public class Ingredient extends AbstractEdible {
    @Transient
    private static final long serialVersionUID = -7669934586986624995L;
    private double kCal;
    private boolean isDessert;

    public Ingredient() {}

    public Ingredient(String name, IngredientCategory category, 
            double kCal, boolean isDessert) {
        this.name = name;
        this.kCal = kCal;
        this.category = category;
        this.isDessert = isDessert;
    }

    @Override
    public double getKCalNonDessert() {
        return isDessert ? 0 : kCal;
    }

    @Override
    public double getKCalDessert() {
        return isDessert ? kCal : 0;
    }
}

抽象食用

package com.singularityfx.kcalibri2.model.edibles;

import java.io.Serializable;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToOne;

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class AbstractEdible implements Edible, Serializable {

    private static final long serialVersionUID = 8684184950268663225L;
    @Id
    protected String name;
    @OneToOne()
    @JoinColumn(name="NAME_OF_CATEGORY")
    protected EdibleCategory category;

    @Override
    public String getName() {
        return name;
    }

    @Override
    public EdibleCategory getCategory() {
        return category;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setCategory(EdibleCategory category) {
        this.category = category;
    }

    @Override
    public String toString() {
        return name + " [" + category + "]";
    }

    @Override
    public int compareTo(Edible c) {
        return name.compareTo(c.getName());
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((category == null) ? 0 : category.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        AbstractEdible other = (AbstractEdible) obj;
        if (category == null) {
            if (other.category != null)
                return false;
        } else if (!category.equals(other.category))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}

可食用

package com.singularityfx.kcalibri2.model.edibles;

import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;

public interface Edible extends Comparable<Edible> {
    public double getKCalNonDessert();
    public double getKCalDessert();
    public String getName();
    public EdibleCategory getCategory();
}

最佳答案

您的 Edible 接口(interface)扩展了 Comparable。因此,您应该在接口(interface)或实现类中覆盖 equalshashCode。连接需要比较无法比较的对象,除非您覆盖 equalshashCode

关于java - 持久映射<实体,双> : having BLOB instead of String key in join table,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28067107/

相关文章:

apache-spark - Spark-Shell 启动错误

java - 尝试运行 derby 时 Eclipse 上出现 "Could not find or load main class org.apache.derby.tools.ij"

java - 使用scala问题分割以点分隔的字符串数字以分隔值

java - 使用 OpenSSL 验证 Java 签名类签名

java - JPA Repository.findByAll() 返回 null 但所有内容都存在于数据库中

java - 谁能告诉我此查询中 spring-data 投影警告的原因吗?

java - JMS 和 JPA 的同步问题

java - Spring boot CrudRepository 保存不良数据

java,重写和等于

java - 是否可以在 Xamarin 中检索存储在 Java 中的 Android 共享首选项