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

bsxbgnwa  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(523)

我想用特定的元素保存两个或更多人之间的关系。一个人用它的技能和一个特定的地址应该互相联系。通常我创建一个表来保存每个元素的id,并在表中创建一行(在普通mysql和php中)。
如何在javaspringboot(jpa-hibernate-mysql)中解决这个问题?
当我从每个元素的存储库中创建(或者更好地请求)一个“对象”(分离)并希望将其保存在一个新的“存储库”(数据库)中时,就出现了一个错误。
PartnerConnectionService实现(.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();
    }
...

partnerconnection(.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); 你有什么简单易懂的建议吗?

00jrzges

00jrzges1#

我认为你的方法应该包含@transactional注解。您已经将所有关系都标记为惰性,因此如果要获取它们,需要一个事务将它们从分离的关系加载到托管状态,然后可以将其附加到要保存的对象

相关问题