I have 2 entities, with 1-to-1 association (ProfileEntity and VCardEntity)
Entity vcard:
@Entity
@Table(name = "vcard")
@AllArgsConstructor
@NoArgsConstructor
@Data
@SequenceGenerator(name="vcard_id_seq_generator", sequenceName="vcard_id_seq", allocationSize = 1)
public class VCardEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "vcard_id_seq_generator")
@Column(name="vcard_id")
Long id;
String account;
@Column(name = "first_name")
String firstName;
@Column(name = "last_name")
String lastName;
@Column(name = "pbxinfo_json")
String pbxInfoJson;
@Column(name = "avatar_id")
String avatarId;
@OneToOne(mappedBy = "vcard")
ProfileEntity profile;
}
entity Profile:
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@Table(name = "profile")
public class ProfileEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "profile_id")
private Long profileId;
private String account;
@Column(name = "product_id")
private String productId;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "vcard_id", referencedColumnName = "vcard_id")
private VCardEntity vcard;
}
I use map struct as follow:
public class CycleAvoidingMappingContext {
private Map<Object, Object> knownInstances = new IdentityHashMap<Object, Object>();
@BeforeMapping
public <T> T getMappedInstance(Object source, @TargetType Class<T> targetType) {
return targetType.cast(knownInstances.get(source));
}
@BeforeMapping
public void storeMappedInstance(Object source, @MappingTarget Object target) {
knownInstances.put( source, target );
}
}
@Mapper(componentModel = "spring")
public interface EntityToProfile {
ProfileEntity profileToEntity(Profile profile, @Context CycleAvoidingMappingContext context);
Profile entityToProfile(ProfileEntity entity, @Context CycleAvoidingMappingContext context);
}
@Mapper(componentModel = "spring")
public interface EntityToVCard {
VCard entityToVcard(VCardEntity entity, @Context CycleAvoidingMappingContext context);
VCardEntity vcardToEntity(VCard vcard, @Context CycleAvoidingMappingContext context);
}
Finally i call mapping in my service:
@Service
@RequiredArgsConstructor
@Slf4j
public class DefaultChatService implements ChatService {
private final ProfileRepository profileRepository;
private final EntityToProfile entityToProfileMapper;
private final EntityToVCard entityToVCardMapper;
@Override
public List<Profile> findAllProfile(Optional<Long> id) {
if (id.isPresent()) {
Optional<ProfileEntity> result = profileRepository.findById(id.get());
if (result.isPresent()) {
Profile profile = entityToProfileMapper.entityToProfile(result.get(), new CycleAvoidingMappingContext());
return Stream.of(profile).collect(Collectors.toList());
}
}
return new ArrayList<Profile>();
}
}
and i got the error ERROR 15976 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause java.lang.StackOverflowError: null
Any thoughts how can i fix it? In my view i did everything as it's written here Prevent Cyclic references when converting with MapStruct but it doesn't work for me