无法持久化具有指向同一表的两个外键的实体

时间:2013-09-27 17:32:27

标签: hibernate jpa one-to-many

我有三个数据库表映射为三个实体:

  • 员工
  • EmployeeToRoom
public class Employee implements Serializable {

@Id
@Column(name = "\"id_emp\"")
private Integer id_emp;

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

@Column(name = "\"surname\"")
private String surname;

...

}
public class Room implements Serializable {

@Id
@Column(name = "\"id_room\"")
private Integer id_room;

@ManyToOne
@JoinColumn(name = "\"id_roomtype\"")
private RoomType type;

@ManyToOne
@JoinColumn(name = "\"id_floor\"")
private Floor floor;

...

}
public class EmployeeToRoom implements Serializable {

@Id
@SequenceGenerator(name = "etr_seq", sequenceName = "etr_seq", allocationSize = 1, initialValue = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "etr_seq")
@Column(name = "\"id\"")
private Integer id;

@ManyToOne
@JoinColumn(name = "\"id_room\"")
private Room room;

@ManyToOne
@JoinColumn(name = "\"id_emp\"")
private Employee employee;

/* Who created/updated record in DB */
@ManyToOne
@JoinColumn(name = "\"who\"")
private Employee who;

/* When was record created/updated */
@Column(name = "\"when\"")
private Timestamp when;

private static final long serialVersionUID = -2059394677268317393L;

...
}

所以我想存储员工在哪个房间工作的信息(以及创建数据库记录的人和时间)。

我用监听器创建了Managed Bean:

@ManagedBean
@ViewScoped
public class EmployeeToRoomBean implements Serializable {
     private static final long serialVersionUID = 1L;
     final javax.persistence.EntityManager em = EntityManager.getEm();
     private Logger log = LoggerFactory.getLogger(EmployeeToRoomBean.class);
     private EmployeeToRoomDaoJPA ETRdao = new EmployeeToRoomDaoJPA();

...

    public void updateListener() {
        TimeStampMaker tsm = new TimeStampMaker();
        ...
        /* Some issues */
        ...
        EmployeeToRoom etrToadd = new EmployeeToRoom();

        etrToadd.setRoom(getEditedRoom());
        etrToadd.setEmployee(employee);
        etrToadd.setWho(UserLogin.getUser().getEmployee());
        etrToadd.setWhen(tsm.getTimestampAsObject());

        ETRdao.create(etrToadd);
        }
}

如果我尝试使用设置值(setRoom(),setEmployee(),setWho(),setWhen())进行记录器输出,一切正常 - 不是空值。

最后我有:

public class EmployeeToRoomDaoJPA implements EmployeeToRoomDao, Serializable {
      private static final long serialVersionUID = 1L;
      private Logger log = LoggerFactory.getLogger(EmployeeToRoomDaoJPA.class);

      ...

      @Override
      public void create(EmployeeToRoom entity) {
            EntityTransaction tx = em.getTransaction();
            try {
                tx.begin();

                this.log.info("Creating new EmployeeToRoom entity:");
                this.log.info("Room: " + entity.getRoom().getId_room());
                this.log.info("Employee: " + entity.getEmployee().getId_emp());
                this.log.info("Who: " + entity.getWho().getId_emp());
                this.log.info("When: " + entity.getWhen().toString());

                em.persist(entity);
                tx.commit();
                this.log.info("done inserting obj " + entity.getId());
            } catch (PersistenceException pe) {
                if (tx != null) {
                   tx.begin();
                   tx.rollback();
                }
              throw pe;
            }
      }
}

这是我的问题。我刚刚收到一个PersistenceException,其中包含查询违反了EmployeeToRoom实体中列Who的非空约束的消息。

但是......我在开始交易后立即添加了记录器输出。 entity.getWho()。getId_emp()中没有null值。

我好几天都无法解决这个问题。正如您所看到的,我在EmployeeToRoom实体/表中有两个外键到Employee实体/表 - 属性Employee和property Who。这可能是我的问题吗?或者其他一切都错了?

非常感谢任何建议。

(Postgres DBMS,Apache Tomcat,Hibernate,JSF2 / Mojarra)

0 个答案:

没有答案