首页 > 解决方案 > SpringBoot2_@Transactional_and_Hibernate

问题描述

我有两个实体和服务的例子:

@ToString(exclude = {"account"})
@EqualsAndHashCode(exclude = {"account"})
@Data
@Table(name = "AUTHOR")
@Entity
public class Author implements Serializable {

    private static final long serialVersionUID = 876978506265052437L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_STORE_ID")
    @SequenceGenerator(name = "SEQ_STORE_ID", sequenceName = "SEQ_STORE_ID", initialValue = 1, allocationSize = 1)
    @Column(name = "ID")
    private Long id;

    @Column(name = "FULLNAME", nullable = false)
    private String fullName;

    @OneToOne(fetch = FetchType.LAZY,  orphanRemoval = true, mappedBy = "author")
    private Account account;
}

@ToString(exclude = {"author"})
@EqualsAndHashCode(exclude = {"author"})
@Entity
@Data
@Table(name = "ACCOUNT")
public class Account implements Serializable {

    private static final long serialVersionUID = -3137902722796945521L;

    @Id
    @Column(name = "ACC_ID")
    private Long id;

    @Column(name = "LOGIN", nullable = false, length = 25)
    private String login;

    @PrimaryKeyJoinColumn
    @OneToOne(fetch = FetchType.LAZY)
    private Author author;

    public void setAuthor(Author author) {
        this.author = author;
        this.id = author != null ? author.getId() : null;
    }
}

服务:

@Slf4j
@Service
public class AuthorService {

    private final AuthorRepository authorRepository;
    private final AccountRepository accountRepository;

    @Autowired
    AuthorService(AuthorRepository authorRepository, AccountRepository accountRepository) {
        this.accountRepository = accountRepository;
        this.authorRepository = authorRepository;
    }

    @Transactional
    public Author createAuthor(@NonNull String authorFullName, @NonNull String login) {
        try {
            Author author = new Author();
            author.setFullName(authorFullName);
            authorRepository.saveAndFlush(author);

            Account account = createAccount(author, login);
            accountRepository.save(account);
            return author;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    Account createAccount(Author author, String login) {
        Account account = new Account();
        account.setAuthor(author);
        account.setLogin(login);
        return account;
    }
}

在我实例化实体Account时的标准输出中,我得到了下一个查询:

2021-05-21 21:39:50.228 DEBUG 33128 --- [nio-9001-exec-1] org.hibernate.SQL                        : 
    select
        account0_.acc_id as acc_id1_0_0_,
        account0_.login as login2_0_0_ 
    from
        account account0_ 
    where
        account0_.acc_id=?
Hibernate: 
    select
        account0_.acc_id as acc_id1_0_0_,
        account0_.login as login2_0_0_ 
    from
        account account0_ 
    where
        account0_.acc_id=?
2021-05-21 21:39:50.229 TRACE 33128 --- [nio-9001-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIGINT] - [55]

问题:为什么我得到错误**“org.hibernate.AssertionFailure:空标识符”**我该如何解决?
DEBUG 向我展示了 SharedSessionContractImplementor#getContextEntityIdentifier 重新调整为 null ,下一步是在新的 org.hibernate.engine.spi.EntityKey(Serializable id, EntityPersister 持久化器) 中捕获该**错误**。
是否与 Transaction 中 Account Entity 的分配 ID 有关?
我怎样才能超越它并以正确的方式做到这一点?

标签: spring-boothibernatetransactions

解决方案


推荐阅读