Přišel jsem sem hledat stejné odpovědi. Ukázalo se, že problém je v tom, že JPA neví, že váš objekt je špinavý. To bylo vyřešeno implementací metod equals()/hashcode() na tyto složité objekty. Ve svém příkladu implementujte rovná se a hashcode pro ProjectProperty
Jakmile je to hotovo, JPA je schopen pomocí těchto metod identifikovat, že základní objekt je špinavý a převádí se a přetrvává.