如何级联插入

时间:2014-01-28 09:49:18

标签: java hibernate foreign-key-relationship

更新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;

1 个答案:

答案 0 :(得分:0)

(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;
    }
}