JPA持久化具有用户提供的值的嵌入式id的新实体

时间:2017-07-07 15:29:28

标签: jpa spring-data-jpa

当嵌入的id值未按顺序排序或生成但由用户输入提供时,如何设置实体保持不变?这种情况是我有一个CustomDeviceType,它有一个CustomDeviceModel列表。当用户创建新的CustomDeviceType时,他们将提供属性,包括用于ID的编号。对于附加到CustomDeviceType的每个CustomDeviceModel也是如此。

因为表devmodels有一个复合主键(dev_type,model_nbr),所以我为CustomDeviceModel创建了一个EmbeddedEd。当我尝试持久化CustomDeviceType时,我收到以下错误:

javax.persistence.EntityNotFoundException: Unable to find com.etisoftware.manager.beans.cborg.devices.CustomDeviceModel with id com.etisoftware.manager.beans.cborg.devices.DeviceModelId@de70

从Hibernates的角度来看,这是有道理的,因为DeviceModeId具有它应该存在于数据库中的值。但事实并非如此。

所以给定这个表设置,我无法改变。如何设置我的实体以便我可以保存新的CustomDeviceModels?

我有两个表devtypes和devmodel:

CREATE TABLE devtypes (
    dev_type integer NOT NULL,
    dev_desc nchar(16) NOT NULL,
    off_premise integer NOT NULL,
    unrouteable integer DEFAULT 0                                                                                                                                                                                                                                                              ,
    custom_models integer DEFAULT 0                                                                                                                                                                                                                                                              ,
    force_case nchar(1) DEFAULT 'U                                                                                                                                                                                                                                                              ',
    has_siblings integer DEFAULT 0                                                                                                                                                                                                                                                              ,
    PRIMARY KEY (dev_type)
);


CREATE TABLE devmodels (
    dev_type integer NOT NULL,
    model_nbr integer NOT NULL,
    model_desc nchar(20),
    cablecard integer DEFAULT 0                                                                                                                                                                                                                                                              ,
    ont_type integer DEFAULT 0                                                                                                                                                                                                                                                               NOT NULL,
    ont_port_type nchar(1) NOT NULL,
    PRIMARY KEY (dev_type,model_nbr)
);

ALTER TABLE devmodels
    ADD CONSTRAINT FOREIGN KEY (dev_type) 
    REFERENCES devtypes (dev_type);

我有以下实体:

@Entity
@Table(name = "devtypes")
public class CustomDeviceType
{
  @Id
  @Column(name = "dev_type")
  private Integer          number;

  @Column(name = "dev_desc")
  private String           name;

  @Column(name = "unrouteable")
  private Boolean          unrouteable;

  @Column(name = "off_premise")
  private Boolean          offPremise;

  @Column(name = "has_siblings")
  private Boolean          hasSiblings;

  @OneToMany(mappedBy = "deviceType", fetch = FetchType.LAZY)
  private Set<CustomDeviceModel> deviceModels;

  // Setters

}



@Entity
@Table(name = "devmodels")
public class CustomDeviceModel
{
  @EmbeddedId
  private DeviceModelId id;

  public CustomDeviceModel()
  {
    id = new DeviceModelId();
  }

  @Column(name = "model_desc")
  private String           name;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "dev_type")
  @MapsId("deviceTypeNumber")
  private CustomDeviceType deviceType;

  @OneToOne(mappedBy = "deviceModel", fetch = FetchType.LAZY)
  @JoinColumns({ @JoinColumn(name = "dev_type"), @JoinColumn(name = "model_nbr") })
  private CustomDeviceTypeConfig deviceConfig;

  public Integer getNumber()
  {
    return id.getNumber();
  }

  public void setNumber(Integer number)
  {
    id.setNumber(number);
  }

  public void setDeviceType(CustomDeviceType deviceType)
  {
    this.deviceType = deviceType;
    id.setDeviceTypeNumber(deviceType.getNumber());
  }

  public CustomDeviceTypeConfig getDeviceConfig()
  {
    return deviceConfig;
  }

  public void setDeviceConfig(CustomDeviceTypeConfig deviceConfig)
  {
    this.deviceConfig = deviceConfig;
    id.setDeviceTypeNumber(deviceConfig.getDeviceModel().getDeviceType().getNumber());
    id.setNumber(deviceConfig.getDeviceModel().getNumber());
  }

  // other setters

}




@Embeddable
public class DeviceModelId implements Serializable
{
  private static final long serialVersionUID = 5215223205194404431L;

  private Integer           deviceTypeNumber;

  @Column(name = "model_nbr")
  private Integer           number;

  public Integer getNumber()
  {
    return number;
  }

  public void setNumber(Integer number)
  {
    this.number = number;
  }

  public Integer getDeviceTypeNumber()
  {
    return deviceTypeNumber;
  }

  public void setDeviceTypeNumber(Integer deviceTypeNumber)
  {
    this.deviceTypeNumber = deviceTypeNumber;
  }

  @Override
  public int hashCode()
  {
    return new HashCodeBuilder().append(deviceTypeNumber).append(number).toHashCode();
  }

  @Override
  public boolean equals(final Object object)
  {
    if (object instanceof DeviceModelId)
    {
      final DeviceModelId other = (DeviceModelId) object;
      return new EqualsBuilder().append(deviceTypeNumber, other.getDeviceTypeNumber()).append(number, other
          .getNumber()).isEquals();
    }
    return false;
  }
}

1 个答案:

答案 0 :(得分:0)

所以这对我来说是一个错误。我忘了添加级联类型。

@OneToMany(mappedBy =&#34; deviceType&#34;,fetch = FetchType.LAZY,cascade = CascadeType.ALL)   private Set deviceModels;