Preciso inserir dados numa tabela que dependerá de chaves estrangeiras e está me dando erros

package conexao.web.Modelo;

import conexao.web.DAO.Conexao;
import java.sql.*;
import javax.swing.JOptionPane;

/**
*

  • @author Cathyana Mário
    */
    public class Funcionario extends Pessoa{
    private int id;
    private Categoria categoria;
    //private Salario salario;
    private Subsidio subsidio;
    private String cargo;
    private Desconto desconto;

    Connection conexao = null;
    PreparedStatement pst = null;
    ResultSet rst = null;

    public Funcionario (){
    conexao = Conexao.conectar();
    }

    public void inserir(Funcionario funcionario, Salario salario, ContaBancaria conta){

     String SQL = "INSERT INTO funcionario (nome, num_bi, NIF, genero, data_nasc, estado_civil, bi_data_val, num_filho, cargo, Categoria_idCategoria                    , Subsidio_idSubsidio, Endereco_idEndereco, Desconto_idDesconto, Contacto_idContacto) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
     
     try {
         pst = conexao.prepareStatement(SQL);                     
         pst.setString  (1, funcionario.getNome());                pst.setString  (2, funcionario.getBi_num());  
         pst.setString  (3, funcionario.getNIF());                 pst.setString  (4, funcionario.getGenero().toString()); 
         pst.setDate    (5, (Date) funcionario.getData_nasc());    pst.setString  (6, funcionario.getEstado_civil());  
         pst.setDate    (7, (Date) funcionario.getBi_data_val());  pst.setInt     (8, funcionario.getNum_filho());        
         pst.setString  (9,  funcionario.getCargo());               pst.setInt     (10, funcionario.getCategoria().getId());
         pst.setInt     (11, funcionario.getSubsidio().getId());   pst.setInt     (12, funcionario.getEndereco().getId()); 
         pst.setInt     (13, funcionario.getDesconto().getId());   pst.setInt     (14, funcionario.getContacto().getId());
         
         
         if(funcionario.getNome().isEmpty() || funcionario.getBi_num().isEmpty() || funcionario.getNIF().isEmpty() || funcionario.getBi_data_val().equals(null)){
             JOptionPane.showMessageDialog(null, "Preencha todos os Campos OBRIGATÓRIO!!!");
         }else{
             if(funcionario.getContacto().disparar(funcionario.getContacto())){
                 if(funcionario.getEndereco().dispararInsert(funcionario.getEndereco())){
                     if(pst.executeUpdate() > 0){
                         funcionario.setId();
                         Salario.disparar(salario);
                         ContaBancaria.dispararInsert(conta);
                         
                         JOptionPane.showMessageDialog(null, "Funcionário cadastrado com SUCESSO!!!");
                     }
                 }           
             }
         }
     } catch (Exception e) {
         JOptionPane.showMessageDialog(null, "ERRO ao cadastrar: "+e);
     }
    

    }

//========================================== MÉTODOS GETTERS E SETTERS ================================================

public Categoria getCategoria() {
    return categoria;
}

public void setCategoria(Categoria categoria) {
    this.categoria = categoria;
}


public Subsidio getSubsidio() {
    return subsidio;
}

public void setSubsidio(Subsidio subsidio) {
    this.subsidio = subsidio;
}

public int getId() {
    return id;
}

public void setId() {
    String SQL = "SELECT MAX(idContacto) FROM contacto";
    
    try {
        pst = conexao.prepareStatement(SQL);
        rst = pst.executeQuery();
        
        if(rst.next())
            this.id = rst.getInt(1);
    } catch (Exception e) {        }
}

public String getCargo() {
    return cargo;
}

public void setCargo(String cargo) {
    this.cargo = cargo;
}

public Desconto getDesconto() {
    return desconto;
}

public void setDesconto(Desconto desconto) {
    this.desconto = desconto;
}        

}

Que erros?