【问题标题】:How to cascade insert如何级联插入
【发布时间】:2014-01-28 09:49:18
【问题描述】:

2014-01-29 更新:我改变了关系,所以实体代码和错误也改变了

我必须在数据库中存储一些数据,我的关系是这样的: Order3d 1-----* 绘制 1-----* 线 我想像这样保存所有内容:

Order3d o=new Order3d();
//add data to order (lines and draws)
Session s=HibernateUtils.getSessionFactory().openSession();
s.save(o);
s.close();

我没有运行时错误,但现在我的行​​没有插入(只保存了 order3d 和 drawfile)

这是我的实体(显然,它们是 POJO,所以我没有复制 getter 和 setter):

@Entity
@Table (name="order3d")
public class Order3d implements Serializable {
    private static final long serialVersionUID = -2241346447352903470L;
    public enum State {DEMAND, ESTIMATED, PAYED, PENDING, PRODUCED, SENT, DELIVERED};
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column (name="id")
    private int id;
    @Column (name="person")
    private int person;
    @Column (name="state", columnDefinition="smallint")
    private State state;
    @Column (name="labor_expense")
    private float laborExpense=0;
    @Column (name="travel_expense")
    private float travelExpense=0;
    @Column (name="validity_date")
    private Date validityDate;
    @Column (name="demand_date")
    private Date demandDate;
    @Column (name="estimate_date")
    private Date estimateDate;
    @Column (name="order_date")
    private Date orderDate=null;
    @Column (name="modification", columnDefinition="TEXT")
    private String modification;
    @Column (name="delivery", columnDefinition = "BIT", length = 1)
    private Boolean delivery=true;
    @OneToMany(mappedBy="order3d", cascade=CascadeType.ALL)
    private Set<DrawFile> myDraws=new HashSet<DrawFile>(5);
    public void addDrawFile(DrawFile df) {
        df.setOrder3d(this);
        myDraws.add(df);
    }
}
@Entity
@Table (name="draw")
public class DrawFile implements Serializable {
    private static final long serialVersionUID = -9024754876558087847L;
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column (name="id")
    private int id;
    @Column (name="hashname", columnDefinition="CHAR(64)")
    private String hashname;
    @Column (name="filename")
    private String filename="";
    @Column (name="accepted", columnDefinition = "BIT", length = 1)
    private Boolean accepted=true;
    @Column (name="format")
    private String format;
    @Column (name="size")
    private int size;
    @Column(name="width")
    short width;
    @Column(name="depth")
    short depth;
    @Column(name="height")
    short height;
    @OneToMany(mappedBy="draw", cascade=CascadeType.ALL)
    private Set<Order3dLine> myLines=new HashSet<Order3dLine>(5);
    @ManyToOne
    @JoinColumn(name="order3d_id")
    private Order3d order3d;
    public void addLine(Order3dLine l) {
        l.setDraw(this);
        myLines.add(l);
    }
}
@Entity
@Table (name="line3d")
public class Order3dLine implements Serializable {
    private static final long serialVersionUID = 3993578603382571145L;
    @NaturalId
    @ManyToOne
    @JoinColumn(name="draw_id")
    private DrawFile draw;
    @Column (name="quantity")
    private short quantity=0;
    @Id
    @Column (name="material")
    private String material;
    @Id
    @Column (name="color")
    private int color;
    @Column(name="produced")
    short produced=0;
    @Column(name="duration")
    short duration=0;
}

这是我的 MySQL 表:

CREATE TABLE `draw` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `filename` varchar(255) DEFAULT NULL,
  `format` varchar(6) DEFAULT NULL,
  `hashname` char(64) DEFAULT NULL,
  `accepted` bit(1) NOT NULL DEFAULT b'0',
  `size` int(11) NOT NULL DEFAULT '0',
  `order3d_id` int(11) NOT NULL,
  `width` smallint(6) NOT NULL DEFAULT '0',
  `depth` smallint(6) NOT NULL DEFAULT '0',
  `height` smallint(6) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  CONSTRAINT `fk_draw_order3d` FOREIGN KEY (`id`) REFERENCES `order3d` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf-8;
/*!40101 SET character_set_client = @saved_cs_client */;

CREATE TABLE `line3d` (
  `draw_id` int(11) NOT NULL,
  `material` varchar(10) NOT NULL,
  `color` int(11) NOT NULL,
  `quantity` smallint(6) NOT NULL DEFAULT '0',
  `produced` smallint(6) NOT NULL DEFAULT '0',
  `duration` smallint(6) NOT NULL DEFAULT '0',
  `layers` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`draw_id`,`material`,`color`),
  CONSTRAINT `fk_line_draw` FOREIGN KEY (`draw_id`) REFERENCES `draw` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf-8;

CREATE TABLE `order3d` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `person` int(11) DEFAULT NULL,
  `state` smallint(6) DEFAULT NULL,
  `labor_expense` float DEFAULT NULL,
  `travel_expense` float DEFAULT NULL,
  `validity_date` date DEFAULT NULL,
  `estimate_date` date DEFAULT NULL,
  `order_date` date DEFAULT NULL,
  `delivery` bit(1) NOT NULL DEFAULT b'0',
  `modification` text,
  `demand_date` date DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_order_user` (`person`),
  CONSTRAINT `fk_order_user` FOREIGN KEY (`person`) REFERENCES `person` (`id`) ON DELETE SET NULL ON UPDATE SET NULL
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf-8;

【问题讨论】:

  • 看起来您的“DrawLine”对象在保存“ObjectLine”对象之前没有持久化。尝试将 'cascade=CascadeType.ALL' 添加到 'OrderLine' 类中的 'DrawLine draw' 中。
  • @Id @OneToOne(fetch = FetchType.LAZY, cascade=CascadeType.ALL) @JoinColumn(name="draw") @Embedded private DrawFile draw; 我还是遇到同样的错误

标签: java hibernate foreign-key-relationship


【解决方案1】:

(1) 订单和订单行之间存在双向关系。 Hibernate 期望您在这种便捷方法中为行分配顺序:

@Entity
@Table(name="ORDERS")       
public class Order {
    [...]

    public void addLine(OrderLine line) {
        line.setOrder(this);
        myLines.add(line);
    }

}

另请参阅this 线程。

(2) “order”不被接受为有效的表表名。例如选择“订单”。

(3) 您忘记了订单线和平局之间的一对一关系中的级联选项。考虑使用@Embedded 而不是@OneToOne。 See Hibernate Doc

我整理了最小的工作示例:

订单:

@Entity
@Table(name = "ORDERS")
public class Order {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column (name = "id")
    private Long id;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name="line_id", nullable = false)
    private Set<OrderLine> lines = new HashSet<OrderLine>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Set<OrderLine> getLines() {
        return lines;
    }

    public void setLines(Set<OrderLine> lines) {
        this.lines = lines;
    }

    public void addLine(OrderLine line) {
        line.setOrder(this);
        lines.add(line);
    }
}

订单行:

@Entity
@Table(name = "ORDER_LINES")
public class OrderLine {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column (name = "id")
    private Long id;

    @ManyToOne(fetch = FetchType.EAGER)
    private Order order;

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

    @Embedded
    private OrderDraw draw;

    public OrderDraw getDraw() {
        return draw;
    }

    public void setDraw(OrderDraw draw) {
        this.draw = draw;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Order getOrder() {
        return order;
    }

    public void setOrder(Order order) {
        this.order = order;
    }
}

订单抽奖(不管是什么)

@Embeddable
public class OrderDraw {
    private int width;
    private int height;

    public OrderDraw() {
        this(0,0);
    }

    public OrderDraw(int width, int height) {
        this.width = width;
        this.height = height;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }
}

【讨论】:

  • 我添加了您的代码并将new Order().getMyLines().add(sometline) ; 替换为new Order().addLine(someline);,我得到了同样的错误:(
  • 请将这些设置添加到您的休眠配置中,并将日志输出附加到您的问题中:hibernate.show_sql=true hibernate.format_sql=true
  • Hibernate: insert into order (delivery, demand_date, estimate_date, labor_expense, modification, order_date, person, state, travel_expense, validity_date) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: select orderlin_.order, orderlin_.material, orderlin_.draw, orderlin_.color, orderlin_.depth as depth3_2_, orderlin_.duration as duration4_2_, orderlin_.height as height5_2_, orderlin_.produced as produced6_2_, orderlin_.quantity as quantity7_2_, orderlin_.width as width8_2_ from line orderlin_ where orderlin_.order=? and orderlin_.material=? and orderlin_.draw=? and orderlin_.color=?
  • 我不知道您使用的是哪个数据库,但我怀疑代码中还有另一个故障:“订单”不是有效的表名。我为您整理了一个工作示例。查看更新的答案。
  • 我真正的表名不是 order 而是 Order3d(我认为这样更简单)。我添加了我的表格创建说明。我不明白映射如何在没有列名的情况下与您的代码一起工作(我也是一个休眠初学者)。我是否需要更改 OrderLine 表中的 order3d 后缀为 _id? (order3d -> order3d_id)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-07
  • 2015-05-15
  • 1970-01-01
  • 2012-09-03
  • 1970-01-01
相关资源
最近更新 更多