[HIBERNATE] Erro ao atualizar um registro

Boa tarde galera,
Então, estou começando agora com o hibernate e estou com um probleminha bem filha da puta.

Eu tenho 3 classes que se relacionam.

Produto
Custos
Custo Direto (custo direto tem fk com produto e com custo)

Até aí tudo certo, consigo gravar o custo_direto, consigo excluir e consigo consultar eles normalmente, porém, quando vou ATUALIZAR o registro, ele dá um erro que tem um Objeto referenciado que ainda não foi salvo bem na hora de dar o commit. E não sei mais como prosseguir depois disso.

Aqui está minha Stacktrace:

javax.persistence.RollbackException: Error while committing the transaction
	at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:94)
	at BD.ConnectionHibernate.commitTransaction(ConnectionHibernate.java:70)
	at DAO.CustoDiretoDAO.saveOrUpdate(CustoDiretoDAO.java:56)
	at GUI.JDCustoDireto.save(JDCustoDireto.java:138)
	at GUI.JDCustoDireto.btGravarActionPerformed(JDCustoDireto.java:368)
	at GUI.JDCustoDireto.access$300(JDCustoDireto.java:30)
	at GUI.JDCustoDireto$4.actionPerformed(JDCustoDireto.java:270)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
	at java.awt.Component.processMouseEvent(Component.java:6505)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3320)
	at java.awt.Component.processEvent(Component.java:6270)
	at java.awt.Container.processEvent(Container.java:2229)
	at java.awt.Component.dispatchEventImpl(Component.java:4861)
	at java.awt.Container.dispatchEventImpl(Container.java:2287)
	at java.awt.Component.dispatchEvent(Component.java:4687)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
	at java.awt.Container.dispatchEventImpl(Container.java:2273)
	at java.awt.Window.dispatchEventImpl(Window.java:2719)
	at java.awt.Component.dispatchEvent(Component.java:4687)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
	at java.awt.EventQueue.access$200(EventQueue.java:103)
	at java.awt.EventQueue$3.run(EventQueue.java:694)
	at java.awt.EventQueue$3.run(EventQueue.java:692)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.awt.EventQueue$4.run(EventQueue.java:708)
	at java.awt.EventQueue$4.run(EventQueue.java:706)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:154)
	at java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:182)
	at java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:221)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.awt.WaitDispatchSupport.enter(WaitDispatchSupport.java:219)
	at java.awt.Dialog.show(Dialog.java:1082)
	at java.awt.Component.show(Component.java:1651)
	at java.awt.Component.setVisible(Component.java:1603)
	at java.awt.Window.setVisible(Window.java:1014)
	at java.awt.Dialog.setVisible(Dialog.java:1005)
	at Panel.JPCustoDireto.updateCustoDireto(JPCustoDireto.java:286)
	at Panel.JPCustoDireto.btEditarActionPerformed(JPCustoDireto.java:577)
	at Panel.JPCustoDireto.access$200(JPCustoDireto.java:40)
	at Panel.JPCustoDireto$2.actionPerformed(JPCustoDireto.java:331)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
	at java.awt.Component.processMouseEvent(Component.java:6505)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3320)
	at java.awt.Component.processEvent(Component.java:6270)
	at java.awt.Container.processEvent(Container.java:2229)
	at java.awt.Component.dispatchEventImpl(Component.java:4861)
	at java.awt.Container.dispatchEventImpl(Container.java:2287)
	at java.awt.Component.dispatchEvent(Component.java:4687)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
	at java.awt.Container.dispatchEventImpl(Container.java:2273)
	at java.awt.Window.dispatchEventImpl(Window.java:2719)
	at java.awt.Component.dispatchEvent(Component.java:4687)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
	at java.awt.EventQueue.access$200(EventQueue.java:103)
	at java.awt.EventQueue$3.run(EventQueue.java:694)
	at java.awt.EventQueue$3.run(EventQueue.java:692)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.awt.EventQueue$4.run(EventQueue.java:708)
	at java.awt.EventQueue$4.run(EventQueue.java:706)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Caused by: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : MODEL.CustoDiretoVO.cd_custo -> MODEL.CustosVO
	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1760)
	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
	at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:82)
	... 88 more
Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : MODEL.CustoDiretoVO.cd_custo -> MODEL.CustosVO
	at org.hibernate.engine.spi.CascadingActions$8.noCascade(CascadingActions.java:398)
	at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:129)
	at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:167)
	at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:158)
	at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:91)
	at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:55)
	at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
	at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
	at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
	at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
	at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77)
	... 88 more

Aqui minha classe Produto:

@Entity
//@SequenceGenerator(name = "seq_produto", sequenceName = "produto_cd_produto_seq", allocationSize = 1, initialValue = 1)
@Table(name = "produto")
public class ProdutoVO implements Serializable {

    @Id
    //@GeneratedValue(generator = "seq_produto", strategy = GenerationType.IDENTITY)
    private Integer cd_produto;
    private String ds_produto;
    private String ds_local;
    private String ds_marca;
    private Integer ativo;
    private Double vl_custo;
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date dt_atual;
    @OneToMany(mappedBy = "cd_produto")
    private List<CustoDiretoVO> cd_custo_direto;

Não vou colocar os getters e setters se não fica muito grande.

Minha classe Custos:

@Entity
@Table(name = "custo")
public class CustosVO implements Serializable{

    @Id
    private Integer cd_custo;
    private String ds_custo;
    private Integer ativo;
    @OneToMany(mappedBy = "cd_custo")
    private List<CustoDiretoVO> cd_custo_direto;

Minha classe Custo Direto:

@Entity
@Table(name = "custo_direto")
public class CustoDiretoVO implements Serializable{

    @Id
    private int cd_custo_direto;
    private double vl_lancto;
    @Temporal(TemporalType.DATE)
    private Date dt_lancto;
    
    @JoinColumn(name = "cd_produto", referencedColumnName = "cd_produto")
    @ManyToOne(optional = false)
    private ProdutoVO cd_produto;
   
    @JoinColumn(name = "cd_custo", referencedColumnName = "cd_custo")
    @ManyToOne(optional = false)
    private CustosVO cd_custo;

Método onde salva:

 public boolean saveOrUpdate(CustoDiretoVO c) {
        try {
            if (connection.activeConnection) {
                CustoDiretoVO custo = connection.em.find(CustoDiretoVO.class, c.getCd_custo_direto());

                connection.beginTransaction();
                
                if (custo != null) {
                      connection.em.merge(c);
                } else {
                       connection.em.persist(c);
                }
                connection.commitTransaction();  //<--------    o erro está acontecendo nessa linha
            }

        } catch (Exception e) {
            e.printStackTrace();
            if (connection.em.getTransaction().isActive()) {
                connection.rollbackTransaction();
            }
            return false;
        }
        return true;
    }

também já tentei usar CascadeType.ALL e o CascadeType.PERSIST mas também não resolveu.

Alguém poderia dar um Help?