有一种我不明白的行为。Spring-Data:生成的值影响更新实体,而不是插入
我要像实体:
@Entity
@EqualsAndHashCode(of={"name"})
@ToString(of={"name", "entityB"})
public class EntityA {
@Id
@GeneratedValue
@Getter
@Setter
private Long id;
@Getter
@Setter
@Column(nullable=false, unique=true)
private String name;
@Getter
@Setter
@ManyToOne(fetch=EAGER, cascade={PERSIST, MERGE})
private EntityB entityB;
}
@ToString(of = { "name" })
@EqualsAndHashCode(of = { "name" })
@Entity
class EntityB {
@Id
@GeneratedValue
@Getter
@Setter
private Long id;
@Getter
@Setter
@XmlAttribute
@Column(nullable=false, unique=true)
private String name;
}
和逻辑将数据插入到数据库:
@Component
public class DatabaseInitializer implements InitializingBean {
@Autowired EntityARepository repository; // Spring-Data CrudRepository!
@Override
public void afterPropertiesSet() throws Exception {
final Set<EntityA> aEntities = createAEntities();
repository.save(aEntities);
Iterator<EntityA> iterator = repository.findAll().iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
private Set<EntityA> createAEntities() throws Exception {
Set<EntityA> aEntities = new HashSet<>();
aEntities.add(getFirstEntityA());
aEntities.add(getSecondEntityA());
return aEntities;
}
private EntityA getFirstEntityA(){
EntityA a = new EntityA();
a.setId(1L);
a.setName("a-1");
a.setEntityB(getFirstEntityB());
return a;
}
private EntityA getSecondEntityA(){
EntityA a = new EntityA();
a.setId(2L);
a.setName("a-2");
a.setEntityB(getFirstEntityB());
return a;
}
//
private EntityB getFirstEntityB() {
EntityB b = new EntityB();
b.setId(1l);
b.setName("b-1");
return b;
}
}
当启动应用程序时,我得到以下的输出:
org.hibernate.SQL: select entitya0_.id as id1_0_1_, entitya0_.entityb_id as entityb_3_0_1_, entitya0_.name as name2_0_1_, entityb1_.id as id1_1_0_, entityb1_.name as name2_1_0_ from entitya entitya0_ left outer join entityb entityb1_ on entitya0_.entityb_id=entityb1_.id where entitya0_.id=?
org.hibernate.SQL: select entityb0_.id as id1_1_0_, entityb0_.name as name2_1_0_ from entityb entityb0_ where entityb0_.id=?
org.hibernate.SQL: insert into entityb (id, name) values (default, ?)
org.hibernate.SQL: insert into entitya (id, entityb_id, name) values (default, ?, ?)
org.hibernate.SQL: update entitya set entityb_id=?, name=? where id=?
EntityA(name=a-1, entityB=EntityB(name=b-1))
由于你可以看到,它更新了entitya,而不是向db添加一个新行。
当我从两个实体中删除@GeneratedValue
它的作品。
org.hibernate.SQL: select entitya0_.id as id1_0_1_, entitya0_.entityb_id as entityb_3_0_1_, entitya0_.name as name2_0_1_, entityb1_.id as id1_1_0_, entityb1_.name as name2_1_0_ from entitya entitya0_ left outer join entityb entityb1_ on entitya0_.entityb_id=entityb1_.id where entitya0_.id=?
org.hibernate.SQL: select entityb0_.id as id1_1_0_, entityb0_.name as name2_1_0_ from entityb entityb0_ where entityb0_.id=?
org.hibernate.SQL: select entitya0_.id as id1_0_1_, entitya0_.entityb_id as entityb_3_0_1_, entitya0_.name as name2_0_1_, entityb1_.id as id1_1_0_, entityb1_.name as name2_1_0_ from entitya entitya0_ left outer join entityb entityb1_ on entitya0_.entityb_id=entityb1_.id where entitya0_.id=?
org.hibernate.SQL: insert into entityb (name, id) values (?, ?)
org.hibernate.SQL: insert into entitya (entityb_id, name, id) values (?, ?, ?)
org.hibernate.SQL: insert into entitya (entityb_id, name, id) values (?, ?, ?)
EntityA(name=a-1, entityB=EntityB(name=b-1))
EntityA(name=a-2, entityB=EntityB(name=b-1))
当我想用ID发电机和实体的创建者删除SETID(...),我得到了一个HsqlException
NullPointerException
。
Caused by: org.hsqldb.HsqlException: java.lang.NullPointerException
at org.hsqldb.error.Error.error(Unknown Source) ~[hsqldb-2.3.3.jar:2.3.3]
at org.hsqldb.persist.RowStoreAVL.indexRow(Unknown Source) ~[hsqldb-2.3.3.jar:2.3.3]
at org.hsqldb.TransactionManager2PL.addInsertAction(Unknown Source) ~[hsqldb-2.3.3.jar:2.3.3]
at org.hsqldb.Session.addInsertAction(Unknown Source) ~[hsqldb-2.3.3.jar:2.3.3]
at org.hsqldb.Table.insertSingleRow(Unknown Source) ~[hsqldb-2.3.3.jar:2.3.3]
at org.hsqldb.StatementDML.insertRowSet(Unknown Source) ~[hsqldb-2.3.3.jar:2.3.3]
at org.hsqldb.StatementInsert.getResult(Unknown Source) ~[hsqldb-2.3.3.jar:2.3.3]
at org.hsqldb.StatementDMQL.execute(Unknown Source) ~[hsqldb-2.3.3.jar:2.3.3]
at org.hsqldb.Session.executeCompiledStatement(Unknown Source) ~[hsqldb-2.3.3.jar:2.3.3]
at org.hsqldb.Session.execute(Unknown Source) ~[hsqldb-2.3.3.jar:2.3.3]
... 87 common frames omitted
Caused by: java.lang.NullPointerException: null
at org.hsqldb.index.IndexAVLMemory.insert(Unknown Source) ~[hsqldb-2.3.3.jar:2.3.3]
... 96 common frames omitted
至少是我想的是,我不`吨需要给entityA一个标识符,它应该由它自己产生,我想至少有两个entitiesA。
您可以请发布完整的堆栈跟踪吗?这可能有帮助。您还使用哪个版本的hsql? –
另外,你可以删除'entityB'的'name'字段上的'unique' constants,并且除去对setId(...)的调用吗?我怀疑它是否为EntityA插入的第二次插入抛出ConstraintViolated异常。 –