Sono venuto qui cercando le stesse risposte. Si scopre che il problema è che JPA non sa che il tuo oggetto è sporco. Questo è stato risolto implementando i metodi equals()/hashcode() su questi oggetti complessi. Nel tuo esempio, implementa equals e hashcode per ProjectProperty
Una volta fatto, JPA è in grado di identificare tramite questi metodi che l'oggetto sottostante è sporco, converte e persiste.