Przybyłem tutaj szukając tych samych odpowiedzi. Okazuje się, że problem polega na tym, że JPA nie wie, że obiekt jest brudny. Zostało to rozwiązane przez zaimplementowanie metod equals()/hashcode() na tych złożonych obiektach. W swoim przykładzie zaimplementuj równania i hashcode dla ProjectProperty
Gdy to zrobisz, JPA jest w stanie zidentyfikować za pomocą tych metod, że bazowy obiekt jest brudny, konwertuje i utrzymuje się.