繁体   English   中英

如何在 java spring 启动(jpa-hibernate)中保存(分离的)对象的关系

[英]How to save relationship of (detached) objects in java spring boot (jpa-hibernate)

我想用特定元素保存两个或更多人的关系。 一个具有其技能和特定地址的人应该相互联系。 Normaly 我创建一个表来保存每个元素的 ID 并在表中创建一行(在普通的 MySQL 中使用 PHP)。
如何解决 Java Spring Boot (JPA-Hibernate-MySQL) 中的这个问题?

当我从每个元素的存储库中创建(或更好地要求)一个“对象”(分离)并希望将其保存在一个新的“存储库”(数据库)中时,我得到了一个错误。

PartnerConnectionServiceImplementation (.java)

@Service
public class PartnerConnectionServiceImpl implements PartnerConnectionService {

    @Autowired
    private PartnerConnectionRepository partnerConnectionRepository;

    @Autowired
    private DanceSkillServiceImpl danceSkillDatabaseService;

    @Autowired
    private AddressLocationServiceImpl addressLocationDatabaseService;

    @Autowired
    private UserProfileServiceImpl userProfileDatabaseService;

@Override
    public Optional<PartnerConnection> connectPartnersWithDanceSkillAndAddressLocation(long userIdPartner1, long danceSkillIdPartner1, long addressLocationIdPartner1, long userIdPartner2, long danceSkillIdPartner2, long addressLocationIdPartner2) {

        Optional<UserProfile> userProfile1 = this.userProfileDatabaseService.getUserById(userIdPartner1);
        Optional<UserProfile> userProfile2 = this.userProfileDatabaseService.getUserById(userIdPartner2);

        Optional<DanceSkill> danceSkill1 = this.danceSkillDatabaseService.getDanceSkillById(danceSkillIdPartner1);
        Optional<DanceSkill> danceSkill2 = this.danceSkillDatabaseService.getDanceSkillById(danceSkillIdPartner2);

        Optional<AddressLocation> addressLocation1 = this.addressLocationDatabaseService.getAddressLocationById(addressLocationIdPartner1);
        Optional<AddressLocation> addressLocation2 = this.addressLocationDatabaseService.getAddressLocationById(addressLocationIdPartner2);

        if (
        (userProfile1.isPresent()) && (userProfile2.isPresent())
        ){
            Optional<PartnerConnection> theConnection = getPartnerConnectionOfPartners(
                    userProfile1.get(),
                    userProfile2.get());

            if (theConnection.isPresent()) {
                return theConnection;
            }
        }


        if (
                (userProfile1.isPresent()) && (userProfile2.isPresent()) &&
                (danceSkill1.isPresent()) && (danceSkill2.isPresent()) &&
                (addressLocation1.isPresent()) && (addressLocation2.isPresent())
        ) {
            PartnerConnection newPartnerConnection = new PartnerConnection(
                null,
                userProfile1.get(),
                danceSkill1.get(),
                addressLocation1.get(),
                userProfile2.get(),
                danceSkill2.get(),
                addressLocation2.get()
        );

        this.partnerConnectionRepository.save(newPartnerConnection);


        return Optional.of(newPartnerConnection);
        }

        return Optional.empty();
    }
...

合作伙伴连接 (.java)


// indicates the connecitons between partners/ users
@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity
@Table(name = "partner_connection")
public class PartnerConnection {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;


    @OneToOne(
            fetch = FetchType.LAZY,
            cascade = CascadeType.ALL
    )
    @JoinColumn(
            name = "firstmessage_fk",    // foreign key
            nullable = true
    )
    private UserMessage firstMessage;

    @ManyToOne(
            fetch = FetchType.LAZY,
            cascade = CascadeType.ALL
    )
    @JoinColumn(name = "onepartner_fk",     // foreign key
            nullable = false)
    private UserProfile firstPartner;

    @OneToOne(
            fetch = FetchType.LAZY,
            cascade = CascadeType.ALL
    )
    @JoinColumn(
            name = "firstpartnerdanceskill_fk",    // foreign key
            nullable = false
    )
    private DanceSkill firstPartnerDanceSkill;

    @OneToOne(fetch = FetchType.LAZY,
            cascade = CascadeType.ALL)
    @JoinColumn(name = "firstpartneraddresslocation_fk",    // foreign key
            nullable = false)
    private AddressLocation firstPartnerAddressLocation;

    @ManyToOne(fetch = FetchType.LAZY,
            cascade = CascadeType.ALL)
    @JoinColumn(name = "secondpartner_fk",   // foreign key
            nullable = false)
    private UserProfile secondPartner;

    @OneToOne(fetch = FetchType.LAZY,
            cascade = CascadeType.ALL)
    @JoinColumn(name = "secondpartnerdanceskill_fk",    // foreign key
            nullable = false)
    private DanceSkill secondPartnerDanceSkill;

    @OneToOne(fetch = FetchType.LAZY,
            cascade = CascadeType.ALL)
    @JoinColumn(name = "secondpartneraddresslocation_fk",    // foreign key
            nullable = false)
    private AddressLocation secondPartnerAddressLocation;


    public PartnerConnection(UserMessage firstMessage, UserProfile firstPartner, DanceSkill firstPartnerDanceSkill, AddressLocation firstPartnerAddressLocation, UserProfile secondPartner, DanceSkill secondPartnerDanceSkill, AddressLocation secondPartnerAddressLocation) {
        this.firstMessage = firstMessage;
        this.firstPartner = firstPartner;
        this.firstPartnerDanceSkill = firstPartnerDanceSkill;
        this.firstPartnerAddressLocation = firstPartnerAddressLocation;
        this.secondPartner = secondPartner;
        this.secondPartnerDanceSkill = secondPartnerDanceSkill;
        this.secondPartnerAddressLocation = secondPartnerAddressLocation;
    }
}

错误org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: ... nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: ...出现在this.partnerConnectionRepository.save(newPartnerConnection);

你有什么简单易懂的建议吗?

我认为您的方法应该包含 @Transactional 注释。 您已将所有关系标记为 LAZY,因此如果您想获取它们,您需要一个事务将它们从分离的关系加载到托管 state 然后能够将其附加到您要保存的 object

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM