我试图使用春天CRUDRepository使用JPA的数据库模型中插入新的对象到数据库(User.java,UserInfo.java)。数据库模型与复合主键相关(UserPK.java),其中一个是自动生成的(字段名为id),第二个(字段名为类型)在开始时设置。春天CrudRepository无法股价生成的ID复合主键
而且我得到的错误,当我创建新的对象,使用CRUDRepository(UserRepository.java) - 不能插入新的对象为第二个模型(UserInfo.java),因为ID为空(第一种模式被正确添加)。我认为问题在于共享/映射数据库模型中的复合主键。 我尝试了与EntityManager相同的模型,它不是错误 - 所有被添加。接下来我用@PrimaryKeyJoinColumns注释,但是与上面的结果相同(但我不确定我是否正确使用它) - CRUDRepository失败,并且EntityManager成功。
任何人都可以帮我找到解决办法吗?如果有人想运行代码,我还会在GitHub上添加源代码。
日志如下:
登录以下CRUDRepository
Hibernate: select user0_.id as id1_0_1_, user0_.type as type2_0_1_, user0_.email as email3_0_1_, user0_.login as login4_0_1_, userinfo1_.id as id3_1_0_, userinfo1_.type as type4_1_0_, userinfo1_.name as name1_1_0_, userinfo1_.surname as surname2_1_0_ from user user0_ left outer join user_info userinfo1_ on user0_.id=userinfo1_.id and user0_.type=userinfo1_.type where user0_.id=? and user0_.type=?
Hibernate: call next value for seq_id
Hibernate: select userinfo0_.id as id3_1_0_, userinfo0_.type as type4_1_0_, userinfo0_.name as name1_1_0_, userinfo0_.surname as surname2_1_0_ from user_info userinfo0_ where userinfo0_.id=? and userinfo0_.type=?
Hibernate: insert into user (email, login, id, type) values (?, ?, ?, ?)
Hibernate: insert into user_info (name, surname, id, type) values (?, ?, ?, ?)
WARN 17653 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 23502, SQLState: 23502
ERROR 17653 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : NULL not allowed for column "ID"; SQL statement:
insert into user_info (name, surname, id, type) values (?, ?, ?, ?) [23502-196]
...
登录的EntityManager
Hibernate: call next value for seq_id
Hibernate: insert into user (email, login, id, type) values (?, ?, ?, ?)
Hibernate: insert into user_info (name, surname, id, type) values (?, ?, ?, ?)
代码:
主要模型:User.java
import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
@Entity
@Table(name = "USER")
@IdClass(UserPK.class)
public class User implements Serializable {
@OneToOne(cascade = CascadeType.ALL, mappedBy = "user")
@JsonManagedReference
private UserInfo info;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ID")
@SequenceGenerator(name = "SEQ_ID", sequenceName = "SEQ_ID", allocationSize = 1)
@NotNull
@Column(name = "ID")
private Long id;
@Id
@NotNull
@Column(name = "TYPE")
private String type;
@NotNull
@Column(name = "LOGIN")
private String login;
@NotNull
@Column(name = "EMAIL")
private String email;
/* ... */
}
第二模型:UserInfo.java
import com.fasterxml.jackson.annotation.JsonBackReference;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name = "USER_INFO")
public class UserInfo implements Serializable {
@Id
@OneToOne(cascade = CascadeType.ALL)
@JoinColumns({
@JoinColumn(name = "id", referencedColumnName = "id"),
@JoinColumn(name = "type", referencedColumnName = "type")
})
@JsonBackReference
@MapsId
private User user;
@Column(name = "NAME")
private String name;
@Column(name = "SURNAME")
private String surname;
/* ... */
}
组成主键:UserPK.java
import java.io.Serializable;
public class UserPK implements Serializable {
private Long id;
private String type;
/* ... */
}
弹簧CRUDRepository:UserRepository.java
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends CrudRepository<User, UserPK> {
User findByIdAndAndType(Long id, String type);
}
库使用的EntityManager:UserRepositoryEM。java的
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
@Repository
@Transactional
public class UserRepositoryEM {
@PersistenceContext
private EntityManager entityManager;
public User findByKey(UserPK key) {
return entityManager.find(User.class, key);
}
public User save(User user) {
entityManager.persist(user);
entityManager.flush();
return user;
}
}
感谢响应,我更改代码,你说:** ** UserPK.java,** ** User.java + ** UserRepository.java **。您可以在[GitHub](https://github.com/kaczla/SpringBootCompositePrimaryKey/tree/embeddedid)上查看更改。现在是其他问题,无法生成密钥 - 即使我设置了密钥,也无法共享到** UserInfo.java ** – kaczla
对UserPK类的wrt序列生成器做了一些修改。现在就试试。 –
我更改** UserPK.java **,但它没有帮助。查看日志,hibernate没有为** UserPK.java **创建序列器,所以自动生成的id不能用@Embeddable注释或者我们做错了。 另一方面,我解决了共享/映射复合主键的问题 - 我只是在** UserInfo.java **中添加了* @ EmbeddedId *注释。当然你可以看到[GitHub](https://github.com/kaczla/SpringBootCompositePrimaryKey/tree/embeddedid) – kaczla