From 1236e1ff4aa62efbdfaeb839079259adf699a02f Mon Sep 17 00:00:00 2001 From: Trebellar Date: Sun, 8 Mar 2026 20:07:17 +0100 Subject: [PATCH] Profesora + Anotaciones mias. --- .gitignore | 55 +++ README.md | 31 ++ pom.xml | 69 +++ .../com/example/hibernate/AccountWindow.java | 409 ++++++++++++++++++ .../hibernate/CreateUpdateAccountDialog.java | 133 ++++++ .../example/hibernate/model/AccMovement.java | 107 +++++ .../com/example/hibernate/model/Account.java | 112 +++++ .../com/example/hibernate/model/Dept.java | 85 ++++ .../java/com/example/hibernate/model/Emp.java | 183 ++++++++ .../com/example/hibernate/model/Project.java | 82 ++++ .../model/dao/AccMovementDaoHibernate.java | 14 + .../model/dao/AccountDaoHibernate.java | 21 + .../model/dao/EmpleadoDaoHibernate.java | 14 + .../hibernate/model/dao/IAccMovementDao.java | 8 + .../hibernate/model/dao/IAccountDao.java | 11 + .../hibernate/model/dao/IEmpleadoDao.java | 8 + .../com/example/hibernate/model/dao/README.md | 1 + .../model/servicio/AccountServicio.java | 79 ++++ .../model/servicio/EmpleadoServicio.java | 28 ++ .../model/servicio/IAccountServicio.java | 20 + .../model/servicio/IEmpleadoServicio.java | 10 + .../model/util/GenericDaoHibernate.java | 89 ++++ .../hibernate/model/util/IGenericDao.java | 67 +++ .../model/util/OperacionHibernate.java | 6 + .../model/util/TransactionManager.java | 28 ++ .../exceptions/InstanceNotFoundException.java | 35 ++ .../example/hibernate/util/HibernateUtil.java | 68 +++ src/main/resources/hibernate.properties | 17 + .../scripts/mariadb/1_scripts_empresa.sql | 131 ++++++ .../scripts/mariadb/2_create_user.sql | 3 + 30 files changed, 1924 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/com/example/hibernate/AccountWindow.java create mode 100644 src/main/java/com/example/hibernate/CreateUpdateAccountDialog.java create mode 100644 src/main/java/com/example/hibernate/model/AccMovement.java create mode 100644 src/main/java/com/example/hibernate/model/Account.java create mode 100644 src/main/java/com/example/hibernate/model/Dept.java create mode 100644 src/main/java/com/example/hibernate/model/Emp.java create mode 100644 src/main/java/com/example/hibernate/model/Project.java create mode 100644 src/main/java/com/example/hibernate/model/dao/AccMovementDaoHibernate.java create mode 100644 src/main/java/com/example/hibernate/model/dao/AccountDaoHibernate.java create mode 100644 src/main/java/com/example/hibernate/model/dao/EmpleadoDaoHibernate.java create mode 100644 src/main/java/com/example/hibernate/model/dao/IAccMovementDao.java create mode 100644 src/main/java/com/example/hibernate/model/dao/IAccountDao.java create mode 100644 src/main/java/com/example/hibernate/model/dao/IEmpleadoDao.java create mode 100644 src/main/java/com/example/hibernate/model/dao/README.md create mode 100644 src/main/java/com/example/hibernate/model/servicio/AccountServicio.java create mode 100644 src/main/java/com/example/hibernate/model/servicio/EmpleadoServicio.java create mode 100644 src/main/java/com/example/hibernate/model/servicio/IAccountServicio.java create mode 100644 src/main/java/com/example/hibernate/model/servicio/IEmpleadoServicio.java create mode 100644 src/main/java/com/example/hibernate/model/util/GenericDaoHibernate.java create mode 100644 src/main/java/com/example/hibernate/model/util/IGenericDao.java create mode 100644 src/main/java/com/example/hibernate/model/util/OperacionHibernate.java create mode 100644 src/main/java/com/example/hibernate/model/util/TransactionManager.java create mode 100644 src/main/java/com/example/hibernate/model/util/exceptions/InstanceNotFoundException.java create mode 100644 src/main/java/com/example/hibernate/util/HibernateUtil.java create mode 100644 src/main/resources/hibernate.properties create mode 100644 src/main/resources/scripts/mariadb/1_scripts_empresa.sql create mode 100644 src/main/resources/scripts/mariadb/2_create_user.sql diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ff811dd --- /dev/null +++ b/.gitignore @@ -0,0 +1,55 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +# https://github.com/takari/maven-wrapper#usage-without-binary-jar +.mvn/wrapper/maven-wrapper.jar + +# Eclipse m2e generated files +# Eclipse Core +.project +# JDT-specific (Eclipse Java Development Tools) +.classpath diff --git a/README.md b/README.md new file mode 100644 index 0000000..bbe9938 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# Respostas ás preguntas da Tarefa03.1 +2- mvn clean generate-sources + + +12- Se añade la opción cascade en Account.java en los getters de AccMovement + +@OneToMany(fetch=FetchType.LAZY, mappedBy="accountByAccountDestId", cascade = CascadeType.REMOVE) + public Set getAccMovementsForAccountDestId() { + return this.accMovementsForAccountDestId; + } + +@OneToMany(fetch=FetchType.LAZY, mappedBy="accountByAccountOriginId", cascade = CascadeType.REMOVE) + public Set getAccMovementsForAccountOriginId() { + return this.accMovementsForAccountOriginId; + } + + + Si no se usasen estas anotaciones, la otra opción sería eliminarlos programáticamente: + @Override + public void delete(Integer accountno) { + transactionManager.ejecutar(() -> { + for (AccMovement accmov : accmovDao.findAll()) { + if (accmov.getAccountByAccountDestId().getAccountno().equals(accountno) || + accmov.getAccountByAccountOriginId().getAccountno().equals(accountno)) { + accmovDao.remove(accmov.getAccountMovId()); + } + } + accountDao.remove(accountno); + return null; + }); + } \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..f3f0707 --- /dev/null +++ b/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + com.example.hibernate + tarea03-1 + 1.0-SNAPSHOT + + + 21 + 21 + + + + + + org.hibernate.tool + hibernate-tools-maven + 6.6.0.Final + + + org.hibernate.tool + hibernate-tools-orm + 6.6.0.Final + + + com.mysql + mysql-connector-j + 9.1.0 + + + + + entity-generation + generate-sources + + hbm2java + + + true + true + com.example.hibernate.model + + src/main/java + + + + + + + + + + org.hibernate + hibernate-core + 6.6.4.Final + + + + com.mysql + mysql-connector-j + 9.1.0 + + + + + \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/AccountWindow.java b/src/main/java/com/example/hibernate/AccountWindow.java new file mode 100644 index 0000000..abf62cb --- /dev/null +++ b/src/main/java/com/example/hibernate/AccountWindow.java @@ -0,0 +1,409 @@ +package com.example.hibernate; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.math.BigDecimal; +import java.util.List; + +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; +import javax.swing.border.EmptyBorder; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import org.hibernate.SessionFactory; + +import com.example.hibernate.model.AccMovement; +import com.example.hibernate.model.Account; +import com.example.hibernate.model.Emp; +import com.example.hibernate.model.dao.AccMovementDaoHibernate; +import com.example.hibernate.model.dao.AccountDaoHibernate; +import com.example.hibernate.model.dao.EmpleadoDaoHibernate; +import com.example.hibernate.model.dao.IAccMovementDao; +import com.example.hibernate.model.dao.IAccountDao; +import com.example.hibernate.model.dao.IEmpleadoDao; +import com.example.hibernate.model.servicio.AccountServicio; +import com.example.hibernate.model.servicio.EmpleadoServicio; +import com.example.hibernate.model.servicio.IAccountServicio; +import com.example.hibernate.model.servicio.IEmpleadoServicio; +import com.example.hibernate.model.util.TransactionManager; +import com.example.hibernate.util.HibernateUtil; + + +public class AccountWindow extends JFrame { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private JPanel contentPane; + + private JTextArea mensajes_text_Area; + private JList JListAllAccounts; + + private IEmpleadoServicio empleadoServicio; + private IAccountServicio accountServicio; + + private CreateUpdateAccountDialog createDialog; + private JButton btnModificarImporteCuenta; + private JButton btnEliminarCuenta; + private JTextField JtextFieldEmpno; + private JLabel lblEmpno; + + private Emp empleado = null; + + /** + * Launch the application. + */ + public static void main(String[] args) { + EventQueue.invokeLater(new Runnable() { + public void run() { + try { + AccountWindow frame = new AccountWindow(); + frame.setVisible(true); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + /** + * Create the frame. + */ + public AccountWindow() { + SessionFactory sessionFactory = HibernateUtil.getInstance().getSessionFactory(); + + TransactionManager transactionManager = new TransactionManager(sessionFactory); + IEmpleadoDao empleadoDao = new EmpleadoDaoHibernate(sessionFactory); + IAccountDao accountDao = new AccountDaoHibernate(sessionFactory); + IAccMovementDao accMovementDao = new AccMovementDaoHibernate(sessionFactory); + empleadoServicio = new EmpleadoServicio(empleadoDao, transactionManager); + accountServicio = new AccountServicio( accMovementDao, accountDao, transactionManager); + + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setBounds(100, 100, 847, 772); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + + setContentPane(contentPane); + contentPane.setLayout(null); + + JPanel panel = new JPanel(); + panel.setBounds(8, 8, 821, 707); + contentPane.add(panel); + panel.setLayout(null); + + JScrollPane scrollPane = new JScrollPane(); + scrollPane.setBounds(19, 450, 669, 228); + panel.add(scrollPane); + + mensajes_text_Area = new JTextArea(); + scrollPane.setViewportView(mensajes_text_Area); + mensajes_text_Area.setEditable(false); + mensajes_text_Area.setText("Panel de mensajes"); + mensajes_text_Area.setForeground(new Color(255, 0, 0)); + mensajes_text_Area.setFont(new Font("Monospaced", Font.PLAIN, 13)); + + JButton btnShowAllAccounts = new JButton("Mostrar cuentas"); + + btnShowAllAccounts.setFont(new Font("Tahoma", Font.PLAIN, 14)); + btnShowAllAccounts.setBounds(38, 132, 208, 36); + panel.add(btnShowAllAccounts); + + JScrollPane scrollPanel_in_JlistAllAccounts = new JScrollPane(); + panel.add(scrollPanel_in_JlistAllAccounts); + + btnModificarImporteCuenta = new JButton("Modificar importe cuenta"); + + JListAllAccounts = new JList(); + + JListAllAccounts.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + panel.add(JListAllAccounts); + JListAllAccounts.setBounds(403, 37, 377, 362); + + JButton btnCrearNuevaAccount = new JButton("Crear nueva cuenta"); + + btnCrearNuevaAccount.setFont(new Font("Tahoma", Font.PLAIN, 14)); + btnCrearNuevaAccount.setBounds(38, 201, 208, 36); + panel.add(btnCrearNuevaAccount); + + btnModificarImporteCuenta.setEnabled(false); + btnModificarImporteCuenta.setFont(new Font("Tahoma", Font.PLAIN, 14)); + btnModificarImporteCuenta.setBounds(38, 266, 208, 36); + panel.add(btnModificarImporteCuenta); + + btnEliminarCuenta = new JButton("Eliminar cuenta"); + + btnEliminarCuenta.setFont(new Font("Tahoma", Font.PLAIN, 14)); + btnEliminarCuenta.setEnabled(false); + btnEliminarCuenta.setBounds(38, 342, 208, 36); + panel.add(btnEliminarCuenta); + + lblEmpno = new JLabel("Introduzca el nº de empleado"); + lblEmpno.setFont(new Font("Tahoma", Font.PLAIN, 14)); + lblEmpno.setBounds(35, 37, 243, 31); + panel.add(lblEmpno); + + JtextFieldEmpno = new JTextField(); + JtextFieldEmpno.setFont(new Font("Tahoma", Font.PLAIN, 14)); + JtextFieldEmpno.setBounds(38, 77, 136, 36); + panel.add(JtextFieldEmpno); + JtextFieldEmpno.setColumns(10); + JtextFieldEmpno.addKeyListener(null); + + // Eventos + ActionListener showAllAccountsActionListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + getAllAccounts(); + } + }; + btnShowAllAccounts.addActionListener(showAllAccountsActionListener); + + ActionListener crearListener = new ActionListener() { + + public void actionPerformed(ActionEvent e) { + int empno = getEmpnoFromTextField(); + try { + + if (empno != -1) { + Account nuevaAcc = new Account(); + + if ((AccountWindow.this.empleado == null) + || (empno != AccountWindow.this.empleado.getEmpno())) { + + AccountWindow.this.empleado = empleadoServicio.find(empno); + } + // Establezco la relación entre la nueva Account y el empleado + nuevaAcc.setEmp(AccountWindow.this.empleado); + JFrame owner = (JFrame) SwingUtilities.getRoot((Component) e.getSource()); + + createDialog = new CreateUpdateAccountDialog(owner, "Crear nueva cuenta", + Dialog.ModalityType.DOCUMENT_MODAL, nuevaAcc); + showDialog(BigDecimal.ZERO); + } else { + addMensaje(true, "El número de empleado no es correcto"); + } + } catch (Exception ex) { + addMensaje(true, "El empno " + empno + " no se encontró"); + } + } + }; + btnCrearNuevaAccount.addActionListener(crearListener); + + ActionListener modificarListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + int selectedIx = JListAllAccounts.getSelectedIndex(); + if (selectedIx > -1) { + // Estas cuentas ya vienen con un proxy de su empleado y con su empno + Account account = (Account) JListAllAccounts.getModel().getElementAt(selectedIx); + if (account != null) { + + JFrame owner = (JFrame) SwingUtilities.getRoot((Component) e.getSource()); + + createDialog = new CreateUpdateAccountDialog(owner, "Modificar importe cuenta", + Dialog.ModalityType.DOCUMENT_MODAL, account); + + showDialog(account.getAmount()); + } + } + } + }; + + btnModificarImporteCuenta.addActionListener(modificarListener); + + ListSelectionListener selectionListListener = new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + if (e.getValueIsAdjusting() == false) { + int selectedIx = JListAllAccounts.getSelectedIndex(); + btnModificarImporteCuenta.setEnabled((selectedIx > -1)); + btnEliminarCuenta.setEnabled((selectedIx > -1)); + + if (selectedIx > -1) { + Account accountd = (Account) JListAllAccounts.getModel().getElementAt(selectedIx); + if (accountd != null) { + addMensaje(true, "Se ha seleccionado la cuenta con id: " + accountd); + } + } + } + } + }; + JListAllAccounts.addListSelectionListener(selectionListListener); + + ActionListener deleteListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + int selectedIx = JListAllAccounts.getSelectedIndex(); + if (selectedIx > -1) { + Account account = (Account) JListAllAccounts.getModel().getElementAt(selectedIx); + if (account != null) { + try { + accountServicio.delete(account.getAccountno()); + + addMensaje(true, "Se ha eliminado la cuenta con id: " + account.getAccountno()); + getAllAccounts(); + + } catch (Exception ex) { + addMensaje(true, "No se ha podido borrar la cuenta. "); + System.out.println("Exception: " + ex.getMessage()); + ex.printStackTrace(); + } + } + } + } + }; + btnEliminarCuenta.addActionListener(deleteListener); + + KeyAdapter enterKeyAdapter = new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + String textIntroducido = ""; + + int key = e.getKeyCode(); + // Cuando se presiona la tecla enter, intentamos obtener el saldo de la cuenta + if ((key == KeyEvent.VK_ENTER)) { + + textIntroducido = ((JTextField) e.getSource()).getText().trim(); + try { + int accId = Integer.parseInt(textIntroducido); + // Se guarda en un atributo de la clase + AccountWindow.this.empleado = empleadoServicio.find(accId); + + if (empleado != null) { + addMensaje(true, "Se ha encontrado el empleado con id: " + accId); + } + + } catch (NumberFormatException nfe) { + + addMensaje(true, "Introduzca un número entero"); + AccountWindow.this.empleado = null; + + + } catch (Exception ex) { + System.out.println("Ha ocurrido una excepción: " + ex.getMessage()); + addMensaje(true, "Ha ocurrido un error y no se ha podido recuperar el empleado con id: " + + textIntroducido); + AccountWindow.this.empleado = null; + + } + } + } + + }; + JtextFieldEmpno.addKeyListener(enterKeyAdapter); + } + + private void addMensaje(boolean keepText, String msg) { + String oldText = ""; + if (keepText) { + oldText = mensajes_text_Area.getText(); + + } + oldText = oldText + "\n" + msg; + mensajes_text_Area.setText(oldText); + + } + + private void showDialog(BigDecimal oldAmount) { + createDialog.setVisible(true); + Account cuentaACrearOActualizar = createDialog.getResult(); + if (cuentaACrearOActualizar != null) { + if (cuentaACrearOActualizar.getAccountno() != null) { + // update + update(cuentaACrearOActualizar, oldAmount); + } else + save(cuentaACrearOActualizar); + } + } + + private void update(Account cuenta, BigDecimal oldAmount) { + addMensaje(true, "La diferencia entre importes es: old:" + oldAmount + " new: " + cuenta.getAmount()); + BigDecimal diferencia = oldAmount.subtract(cuenta.getAmount()); + // oldAmount < cantidad actual, diferencia es negativa-> se ha ingresado dinero + // +diferencia + // oldAmount > cantidad actual, diferencia es positiva-> se ha retirado dinero + // -diferencia + // si cantidades iguales no hacemos nada + // En el movimiento hay que invertir los signos + + if (diferencia.compareTo(BigDecimal.ZERO) != 0) { + try { + AccMovement movimiento = accountServicio.autoTransferir(cuenta.getAccountno(), + diferencia.doubleValue() * (-1)); + + getAllAccounts(); + addMensaje(true, "Se ha creado el movimiento: " + movimiento); + + + } catch (Exception e2) { + addMensaje(true, "No se ha podido modificar la cuenta con número: " + cuenta.getAccountno()); + + } + } else { + addMensaje(true, "No ha habido variación de cantidad en la cuenta" + cuenta.getAccountno()); + } + + } + + private void save(Account cuenta) { + try { + accountServicio.crear(cuenta); + + addMensaje(true, "Se ha creado una cuenta con id: " + cuenta.getAccountno()); + getAllAccounts(); + + + } catch (Exception ex) { + addMensaje(true, "Ha ocurrido un error y no se ha podido crear la cuenta"); + } + } + + private void getAllAccounts() { + int empno = getEmpnoFromTextField(); + if (empno != -1) { + try { + List accounts = accountServicio.getAccountsByEmpno(empno); + addMensaje(true, "Se han recuperado: " + accounts.size() + " cuentas"); + DefaultListModel defModel = new DefaultListModel<>(); + + defModel.addAll(accounts); + + JListAllAccounts.setModel(defModel); + } catch (Exception ex) { + ex.printStackTrace(); + addMensaje(true, "Ha habido un error y no se han podido recuperar las cuentas del empleado: " + empno); + } + } else { + addMensaje(true, "El número de empleado no es correcto"); + } + + } + + private int getEmpnoFromTextField() { + int empno = -1; + String textIntroducido = JtextFieldEmpno.getText().trim(); + try { + empno = Integer.parseInt(textIntroducido); + } catch (Exception nfe) { + empno = -1; + } + return empno; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/CreateUpdateAccountDialog.java b/src/main/java/com/example/hibernate/CreateUpdateAccountDialog.java new file mode 100644 index 0000000..703d9ac --- /dev/null +++ b/src/main/java/com/example/hibernate/CreateUpdateAccountDialog.java @@ -0,0 +1,133 @@ +package com.example.hibernate; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.math.BigDecimal; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.border.EmptyBorder; + +import com.example.hibernate.model.Account; + +public class CreateUpdateAccountDialog extends JDialog { + + /** + * + */ + private static final long serialVersionUID = 1L; + private final JPanel contentPanel = new JPanel(); + private JTextField textFieldAmount; + private JButton okButton; + private JLabel lblError=null; + + private Account cuentaACrearOActualizar = null; + + public Account getResult() { + return this.cuentaACrearOActualizar; + } + + /** + * Create the dialog. + */ + public void initComponents() { + + setBounds(100, 100, 450, 300); + getContentPane().setLayout(new BorderLayout()); + contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); + getContentPane().add(contentPanel, BorderLayout.CENTER); + contentPanel.setLayout(null); + + JLabel lblImporte = new JLabel("Importe cuenta"); + lblImporte.setFont(new Font("Tahoma", Font.PLAIN, 14)); + lblImporte.setBounds(46, 76, 140, 24); + contentPanel.add(lblImporte); + + textFieldAmount = new JTextField(); + textFieldAmount.setFont(new Font("Tahoma", Font.PLAIN, 14)); + textFieldAmount.setBounds(215, 77, 197, 23); + contentPanel.add(textFieldAmount); + textFieldAmount.setColumns(10); + + lblError = new JLabel("Importe inicial"); + lblError.setVisible(false); + lblError.setForeground(new Color(255, 0, 0)); + lblError.setFont(new Font("Tahoma", Font.PLAIN, 14)); + lblError.setBounds(33, 169, 379, 24); + contentPanel.add(lblError); + + JPanel buttonPane = new JPanel(); + buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT)); + getContentPane().add(buttonPane, BorderLayout.SOUTH); + + okButton = new JButton("Guardar"); + + okButton.setActionCommand("OK"); + buttonPane.add(okButton); + getRootPane().setDefaultButton(okButton); + + JButton cancelButton = new JButton("Cancel"); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + cuentaACrearOActualizar = null; + CreateUpdateAccountDialog.this.dispose(); + + } + }); + cancelButton.setActionCommand("Cancel"); + buttonPane.add(cancelButton); + + ActionListener crearBtnActionListener = new ActionListener() { + + public void actionPerformed(ActionEvent e) { + if (!(textFieldAmount.getText().trim().equals(""))) { + try { + BigDecimal cantidad = getAmountFromTextField(); + + cuentaACrearOActualizar.setAmount(cantidad); + CreateUpdateAccountDialog.this.dispose(); + } catch (Exception ex) { + System.out.println("Ha ocurrido un problema obteniendo la cantidad: " + ex.getMessage()); + lblError.setText("La cantidad introducida no es correcta"); + lblError.setVisible(true); + + } + + } + } + }; + + this.okButton.addActionListener(crearBtnActionListener); + + } + + public CreateUpdateAccountDialog(Window owner, String title, ModalityType modalityType, Account acc) { + super(owner, title, modalityType); + initComponents(); + cuentaACrearOActualizar = acc; + lblError.setVisible(false); + if (cuentaACrearOActualizar != null && cuentaACrearOActualizar.getAmount()!=null ) { + + textFieldAmount.setText(cuentaACrearOActualizar.getAmount().toString()); + + } + this.setLocationRelativeTo(owner); + } + + private BigDecimal getAmountFromTextField() throws NumberFormatException { + + lblError.setVisible(false); + String textIntroducido = textFieldAmount.getText().trim(); + + return new BigDecimal(textIntroducido); + + } +} \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/model/AccMovement.java b/src/main/java/com/example/hibernate/model/AccMovement.java new file mode 100644 index 0000000..d97cb7c --- /dev/null +++ b/src/main/java/com/example/hibernate/model/AccMovement.java @@ -0,0 +1,107 @@ +package com.example.hibernate.model; +// Generated 19 feb 2026, 19:19:40 by Hibernate Tools 6.6.0.Final + + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import static jakarta.persistence.GenerationType.IDENTITY; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +// import jakarta.persistence.Temporal; +// import jakarta.persistence.TemporalType; +import java.math.BigDecimal; +//import java.sql.Timestamp; +import java.time.LocalDateTime; + +/** + * AccMovement generated by hbm2java + */ +@Entity +@Table(name="acc_movement" +) +public class AccMovement implements java.io.Serializable { + + + @Override + public String toString() { + return "AccMovement [accountMovId=" + accountMovId + ", amount=" + amount + ", datetime=" + datetime + "]"; + } + + private Integer accountMovId; + private Account accountByAccountDestId; + private Account accountByAccountOriginId; + private BigDecimal amount; + private LocalDateTime datetime; + + public AccMovement() { + } + + public AccMovement(Account accountByAccountDestId, Account accountByAccountOriginId, BigDecimal amount, LocalDateTime datetime) { + this.accountByAccountDestId = accountByAccountDestId; + this.accountByAccountOriginId = accountByAccountOriginId; + this.amount = amount; + this.datetime = datetime; + } + + @Id @GeneratedValue(strategy=IDENTITY) + + + @Column(name="ACCOUNT_MOV_ID", unique=true, nullable=false) + public Integer getAccountMovId() { + return this.accountMovId; + } + + public void setAccountMovId(Integer accountMovId) { + this.accountMovId = accountMovId; + } + +@ManyToOne(fetch=FetchType.LAZY) + @JoinColumn(name="ACCOUNT_DEST_ID", nullable=false) + public Account getAccountByAccountDestId() { + return this.accountByAccountDestId; + } + + public void setAccountByAccountDestId(Account accountByAccountDestId) { + this.accountByAccountDestId = accountByAccountDestId; + } + +@ManyToOne(fetch=FetchType.LAZY) + @JoinColumn(name="ACCOUNT_ORIGIN_ID", nullable=false) + public Account getAccountByAccountOriginId() { + return this.accountByAccountOriginId; + } + + public void setAccountByAccountOriginId(Account accountByAccountOriginId) { + this.accountByAccountOriginId = accountByAccountOriginId; + } + + + @Column(name="AMOUNT", nullable=false, precision=19, scale=4) + public BigDecimal getAmount() { + return this.amount; + } + + public void setAmount(BigDecimal amount) { + this.amount = amount; + } + + // @Temporal(TemporalType.TIMESTAMP) + @Column(name="DATETIME", nullable=false, length=19) + public LocalDateTime getDatetime() { + return this.datetime; + } + + public void setDatetime(LocalDateTime datetime) { + this.datetime = datetime; + } + + + + +} + + diff --git a/src/main/java/com/example/hibernate/model/Account.java b/src/main/java/com/example/hibernate/model/Account.java new file mode 100644 index 0000000..da1f358 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/Account.java @@ -0,0 +1,112 @@ +package com.example.hibernate.model; +// Generated 19 feb 2026, 19:19:40 by Hibernate Tools 6.6.0.Final + + +import static jakarta.persistence.GenerationType.IDENTITY; + +import java.math.BigDecimal; +import java.util.HashSet; +import java.util.Set; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; + +/** + * Account generated by hbm2java + */ +@Entity +@Table(name="account" +) +public class Account implements java.io.Serializable { + + + @Override + public String toString() { + return "Account [accountno=" + accountno + ", amount=" + amount + "]"; + } + + private Integer accountno; + private Emp emp; + private BigDecimal amount; + private Set accMovementsForAccountDestId = new HashSet(0); + private Set accMovementsForAccountOriginId = new HashSet(0); + + public Account() { + } + + + public Account(Emp emp, BigDecimal amount) { + this.emp = emp; + this.amount = amount; + } + public Account(Emp emp, BigDecimal amount, Set accMovementsForAccountDestId, Set accMovementsForAccountOriginId) { + this.emp = emp; + this.amount = amount; + this.accMovementsForAccountDestId = accMovementsForAccountDestId; + this.accMovementsForAccountOriginId = accMovementsForAccountOriginId; + } + + @Id @GeneratedValue(strategy=IDENTITY) + + + @Column(name="ACCOUNTNO", unique=true, nullable=false) + public Integer getAccountno() { + return this.accountno; + } + + public void setAccountno(Integer accountno) { + this.accountno = accountno; + } + +@ManyToOne(fetch=FetchType.LAZY) + @JoinColumn(name="EMPNO", nullable=false) + public Emp getEmp() { + return this.emp; + } + + public void setEmp(Emp emp) { + this.emp = emp; + } + + + @Column(name="AMOUNT", nullable=false, precision=19, scale=4) + public BigDecimal getAmount() { + return this.amount; + } + + public void setAmount(BigDecimal amount) { + this.amount = amount; + } + +@OneToMany(fetch=FetchType.LAZY, mappedBy="accountByAccountDestId", cascade = CascadeType.REMOVE) + public Set getAccMovementsForAccountDestId() { + return this.accMovementsForAccountDestId; + } + + public void setAccMovementsForAccountDestId(Set accMovementsForAccountDestId) { + this.accMovementsForAccountDestId = accMovementsForAccountDestId; + } + +@OneToMany(fetch=FetchType.LAZY, mappedBy="accountByAccountOriginId", cascade = CascadeType.REMOVE) + public Set getAccMovementsForAccountOriginId() { + return this.accMovementsForAccountOriginId; + } + + public void setAccMovementsForAccountOriginId(Set accMovementsForAccountOriginId) { + this.accMovementsForAccountOriginId = accMovementsForAccountOriginId; + } + + + + +} + + diff --git a/src/main/java/com/example/hibernate/model/Dept.java b/src/main/java/com/example/hibernate/model/Dept.java new file mode 100644 index 0000000..62f94d5 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/Dept.java @@ -0,0 +1,85 @@ +package com.example.hibernate.model; +// Generated 19 feb 2026, 19:19:40 by Hibernate Tools 6.6.0.Final + + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import static jakarta.persistence.GenerationType.IDENTITY; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import java.util.HashSet; +import java.util.Set; + +/** + * Dept generated by hbm2java + */ +@Entity +@Table(name="dept" +) +public class Dept implements java.io.Serializable { + + + private Integer deptno; + private String dname; + private String loc; + private Set emps = new HashSet(0); + + public Dept() { + } + + public Dept(String dname, String loc, Set emps) { + this.dname = dname; + this.loc = loc; + this.emps = emps; + } + + @Id @GeneratedValue(strategy=IDENTITY) + + + @Column(name="DEPTNO", unique=true, nullable=false) + public Integer getDeptno() { + return this.deptno; + } + + public void setDeptno(Integer deptno) { + this.deptno = deptno; + } + + + @Column(name="DNAME", length=20) + public String getDname() { + return this.dname; + } + + public void setDname(String dname) { + this.dname = dname; + } + + + @Column(name="LOC", length=20) + public String getLoc() { + return this.loc; + } + + public void setLoc(String loc) { + this.loc = loc; + } + +@OneToMany(fetch=FetchType.LAZY, mappedBy="dept") + public Set getEmps() { + return this.emps; + } + + public void setEmps(Set emps) { + this.emps = emps; + } + + + + +} + + diff --git a/src/main/java/com/example/hibernate/model/Emp.java b/src/main/java/com/example/hibernate/model/Emp.java new file mode 100644 index 0000000..53f3207 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/Emp.java @@ -0,0 +1,183 @@ +package com.example.hibernate.model; +// Generated 19 feb 2026, 19:19:40 by Hibernate Tools 6.6.0.Final + + +import static jakarta.persistence.GenerationType.IDENTITY; + +// import jakarta.persistence.Temporal; +// import jakarta.persistence.TemporalType; +import java.math.BigDecimal; +import java.time.LocalDate; + +//import java.sql.Date; +import java.util.HashSet; +import java.util.Set; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; + +/** + * Emp generated by hbm2java + */ +@Entity +@Table(name="emp" +) +public class Emp implements java.io.Serializable { + + + private Integer empno; + private Dept dept; + private Emp jefe; + private String ename; + private String job; + private LocalDate hiredate; + private BigDecimal sal; + private BigDecimal comm; + private Set accounts = new HashSet(0); + private Set projects = new HashSet(0); + private Set emps = new HashSet(0); + + public Emp() { + } + + public Emp(Dept dept, Emp emp, String ename, String job, LocalDate hiredate, BigDecimal sal, BigDecimal comm, Set accounts, Set projects, Set emps) { + this.dept = dept; + this.jefe = emp; + this.ename = ename; + this.job = job; + this.hiredate = hiredate; + this.sal = sal; + this.comm = comm; + this.accounts = accounts; + this.projects = projects; + this.emps = emps; + } + + @Id @GeneratedValue(strategy=IDENTITY) + + + @Column(name="EMPNO", unique=true, nullable=false) + public Integer getEmpno() { + return this.empno; + } + + public void setEmpno(Integer empno) { + this.empno = empno; + } + +@ManyToOne(fetch=FetchType.LAZY) + @JoinColumn(name="DEPTNO") + public Dept getDept() { + return this.dept; + } + + public void setDept(Dept dept) { + this.dept = dept; + } + +@ManyToOne(fetch=FetchType.LAZY) + @JoinColumn(name="MGR") + public Emp getJefe() { + return this.jefe; + } + + public void setJefe(Emp emp) { + this.jefe = emp; + } + + + @Column(name="ENAME", length=20) + public String getEname() { + return this.ename; + } + + public void setEname(String ename) { + this.ename = ename; + } + + + @Column(name="JOB", length=20) + public String getJob() { + return this.job; + } + + public void setJob(String job) { + this.job = job; + } + + //@Temporal(TemporalType.DATE) + @Column(name="HIREDATE", length=10) + public LocalDate getHiredate() { + return this.hiredate; + } + + public void setHiredate(LocalDate hiredate) { + this.hiredate = hiredate; + } + + + @Column(name="SAL", precision=15, scale=2) + public BigDecimal getSal() { + return this.sal; + } + + public void setSal(BigDecimal sal) { + this.sal = sal; + } + + + @Column(name="COMM", precision=15, scale=2) + public BigDecimal getComm() { + return this.comm; + } + + public void setComm(BigDecimal comm) { + this.comm = comm; + } + +@OneToMany(fetch=FetchType.LAZY, mappedBy="emp") + public Set getAccounts() { + return this.accounts; + } + + public void setAccounts(Set accounts) { + this.accounts = accounts; + } + +@ManyToMany(fetch=FetchType.LAZY, mappedBy = "emps") + // @JoinTable(name="project_emp", catalog="empresa", joinColumns = { + // @JoinColumn(name="EMPNO", nullable=false, updatable=false) }, inverseJoinColumns = { + // @JoinColumn(name="PROJECTNO", nullable=false, updatable=false) }) + public Set getProjects() { + return this.projects; + } + + public void setProjects(Set projects) { + this.projects = projects; + } + +@OneToMany(fetch=FetchType.LAZY, mappedBy="jefe") + public Set getEmps() { + return this.emps; + } + + public void setEmps(Set emps) { + this.emps = emps; + } + + + + +} + + diff --git a/src/main/java/com/example/hibernate/model/Project.java b/src/main/java/com/example/hibernate/model/Project.java new file mode 100644 index 0000000..328ec76 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/Project.java @@ -0,0 +1,82 @@ +package com.example.hibernate.model; +// Generated 19 feb 2026, 19:19:40 by Hibernate Tools 6.6.0.Final + + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import static jakarta.persistence.GenerationType.IDENTITY; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.Table; +import java.util.HashSet; +import java.util.Set; + +/** + * Project generated by hbm2java + */ +@Entity +@Table(name="project" +) +public class Project implements java.io.Serializable { + + + private Integer projno; + private String projname; + private Set emps = new HashSet(0); + + public Project() { + } + + + public Project(String projname) { + this.projname = projname; + } + public Project(String projname, Set emps) { + this.projname = projname; + this.emps = emps; + } + + @Id @GeneratedValue(strategy=IDENTITY) + + + @Column(name="PROJNO", unique=true, nullable=false) + public Integer getProjno() { + return this.projno; + } + + public void setProjno(Integer projno) { + this.projno = projno; + } + + + @Column(name="PROJNAME", nullable=false, length=50) + public String getProjname() { + return this.projname; + } + + public void setProjname(String projname) { + this.projname = projname; + } + +@ManyToMany(fetch=FetchType.LAZY) + @JoinTable(name="project_emp", catalog="empresa", joinColumns = { + @JoinColumn(name="PROJECTNO", nullable=false) }, inverseJoinColumns = { + @JoinColumn(name="EMPNO", nullable=false) }) + public Set getEmps() { + return this.emps; + } + + public void setEmps(Set emps) { + this.emps = emps; + } + + + + +} + + diff --git a/src/main/java/com/example/hibernate/model/dao/AccMovementDaoHibernate.java b/src/main/java/com/example/hibernate/model/dao/AccMovementDaoHibernate.java new file mode 100644 index 0000000..1de5e43 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/dao/AccMovementDaoHibernate.java @@ -0,0 +1,14 @@ +package com.example.hibernate.model.dao; + +import org.hibernate.SessionFactory; + +import com.example.hibernate.model.AccMovement; +import com.example.hibernate.model.util.GenericDaoHibernate; + + +public class AccMovementDaoHibernate extends GenericDaoHibernate implements IAccMovementDao { + public AccMovementDaoHibernate(SessionFactory sessionFactory) { + super(sessionFactory); + } + +} diff --git a/src/main/java/com/example/hibernate/model/dao/AccountDaoHibernate.java b/src/main/java/com/example/hibernate/model/dao/AccountDaoHibernate.java new file mode 100644 index 0000000..3f215ab --- /dev/null +++ b/src/main/java/com/example/hibernate/model/dao/AccountDaoHibernate.java @@ -0,0 +1,21 @@ +package com.example.hibernate.model.dao; + +import java.util.List; + +import org.hibernate.SessionFactory; + +import com.example.hibernate.model.Account; +import com.example.hibernate.model.util.GenericDaoHibernate; + + +public class AccountDaoHibernate extends GenericDaoHibernate implements IAccountDao { + public AccountDaoHibernate(SessionFactory sessionFactory) { + super(sessionFactory); + } + + @Override + public List< Account> getAccountsByEmpno(Integer empno) { + return getSession().createSelectionQuery("from Account where emp.empno = :empno", Account.class) + .setParameter("empno", empno).getResultList(); + } +} diff --git a/src/main/java/com/example/hibernate/model/dao/EmpleadoDaoHibernate.java b/src/main/java/com/example/hibernate/model/dao/EmpleadoDaoHibernate.java new file mode 100644 index 0000000..5094678 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/dao/EmpleadoDaoHibernate.java @@ -0,0 +1,14 @@ +package com.example.hibernate.model.dao; + +import org.hibernate.SessionFactory; + +import com.example.hibernate.model.Emp; +import com.example.hibernate.model.util.GenericDaoHibernate; + + +public class EmpleadoDaoHibernate extends GenericDaoHibernate implements IEmpleadoDao { + public EmpleadoDaoHibernate(SessionFactory sessionFactory) { + super(sessionFactory); + } + +} diff --git a/src/main/java/com/example/hibernate/model/dao/IAccMovementDao.java b/src/main/java/com/example/hibernate/model/dao/IAccMovementDao.java new file mode 100644 index 0000000..540aa8d --- /dev/null +++ b/src/main/java/com/example/hibernate/model/dao/IAccMovementDao.java @@ -0,0 +1,8 @@ +package com.example.hibernate.model.dao; + +import com.example.hibernate.model.AccMovement; +import com.example.hibernate.model.util.IGenericDao; + +public interface IAccMovementDao extends IGenericDao { + +} diff --git a/src/main/java/com/example/hibernate/model/dao/IAccountDao.java b/src/main/java/com/example/hibernate/model/dao/IAccountDao.java new file mode 100644 index 0000000..2103efa --- /dev/null +++ b/src/main/java/com/example/hibernate/model/dao/IAccountDao.java @@ -0,0 +1,11 @@ +package com.example.hibernate.model.dao; + +import java.util.List; + +import com.example.hibernate.model.Account; +import com.example.hibernate.model.util.IGenericDao; + +public interface IAccountDao extends IGenericDao { + + public List getAccountsByEmpno(Integer empno); +} diff --git a/src/main/java/com/example/hibernate/model/dao/IEmpleadoDao.java b/src/main/java/com/example/hibernate/model/dao/IEmpleadoDao.java new file mode 100644 index 0000000..5ae87d8 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/dao/IEmpleadoDao.java @@ -0,0 +1,8 @@ +package com.example.hibernate.model.dao; + +import com.example.hibernate.model.Emp; +import com.example.hibernate.model.util.IGenericDao; + +public interface IEmpleadoDao extends IGenericDao { + +} diff --git a/src/main/java/com/example/hibernate/model/dao/README.md b/src/main/java/com/example/hibernate/model/dao/README.md new file mode 100644 index 0000000..f364a2f --- /dev/null +++ b/src/main/java/com/example/hibernate/model/dao/README.md @@ -0,0 +1 @@ +# En esta carpeta deberíais añadir las clases e interfaces DAO \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/model/servicio/AccountServicio.java b/src/main/java/com/example/hibernate/model/servicio/AccountServicio.java new file mode 100644 index 0000000..9ef6213 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/servicio/AccountServicio.java @@ -0,0 +1,79 @@ +package com.example.hibernate.model.servicio; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +import com.example.hibernate.model.AccMovement; +import com.example.hibernate.model.Account; +import com.example.hibernate.model.dao.IAccMovementDao; +import com.example.hibernate.model.dao.IAccountDao; +import com.example.hibernate.model.util.TransactionManager; + +public class AccountServicio implements IAccountServicio { + + private IAccountDao accountDao; + private IAccMovementDao accmovDao; + private TransactionManager transactionManager; + + public AccountServicio(IAccMovementDao accmovDao, IAccountDao accountDao, TransactionManager transactionManager) { + this.accountDao = accountDao; + this.accmovDao = accmovDao; + this.transactionManager = transactionManager; + } + + public List getAccountsByEmpno(Integer empno) { + return transactionManager.ejecutar(() -> accountDao.getAccountsByEmpno(empno)); + + } + + @Override + public AccMovement autoTransferir(Integer accountno, double diferencia) { + return transactionManager.ejecutar(() -> { + Account account = accountDao.find(accountno); + double saldoAnterior = account.getAmount().doubleValue(); + double saldoNuevo = saldoAnterior + diferencia; + account.setAmount(BigDecimal.valueOf(saldoNuevo)); + accountDao.update(account); + + AccMovement accmov = new AccMovement(); + accmov.setAccountByAccountDestId(account); + accmov.setAccountByAccountOriginId(account); + accmov.setAmount(BigDecimal.valueOf(diferencia)); + accmov.setDatetime(LocalDateTime.now()); + + accmovDao.create(accmov); + return accmov; + }); + } + + @Override + public void crear(Account account) { + transactionManager.ejecutar(() -> { + accountDao.create(account); + return null; + }); + } + + @Override + public void update(Account account) { + transactionManager.ejecutar(() -> { + accountDao.update(account); + return null; + }); + } + + @Override + public void delete(Integer accountno) { + transactionManager.ejecutar(() -> { + // for (AccMovement accmov : accmovDao.findAll()) { + // if (accmov.getAccountByAccountDestId().getAccountno().equals(accountno) || + // accmov.getAccountByAccountOriginId().getAccountno().equals(accountno)) { + // accmovDao.remove(accmov.getAccountMovId()); + // } + // } + accountDao.remove(accountno); + return null; + }); + } +} diff --git a/src/main/java/com/example/hibernate/model/servicio/EmpleadoServicio.java b/src/main/java/com/example/hibernate/model/servicio/EmpleadoServicio.java new file mode 100644 index 0000000..498ff93 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/servicio/EmpleadoServicio.java @@ -0,0 +1,28 @@ +package com.example.hibernate.model.servicio; + + +import com.example.hibernate.model.Emp; +import com.example.hibernate.model.dao.EmpleadoDaoHibernate; +import com.example.hibernate.model.dao.IEmpleadoDao; +import com.example.hibernate.model.util.TransactionManager; +import com.example.hibernate.model.util.exceptions.InstanceNotFoundException; + + + +public class EmpleadoServicio implements IEmpleadoServicio { + + private IEmpleadoDao empleadoDao; + + + private TransactionManager transactionManager; + public EmpleadoServicio(IEmpleadoDao empleadoDao, TransactionManager transactionManager) { + this.empleadoDao = empleadoDao; + this.transactionManager = transactionManager; + } + + public Emp find(Integer empno) throws InstanceNotFoundException { + return transactionManager.ejecutar(() -> empleadoDao.find(empno)); + } + + +} diff --git a/src/main/java/com/example/hibernate/model/servicio/IAccountServicio.java b/src/main/java/com/example/hibernate/model/servicio/IAccountServicio.java new file mode 100644 index 0000000..c28dff3 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/servicio/IAccountServicio.java @@ -0,0 +1,20 @@ +package com.example.hibernate.model.servicio; + +import java.util.List; + +import com.example.hibernate.model.AccMovement; +import com.example.hibernate.model.Account; + +public interface IAccountServicio { + + public AccMovement autoTransferir(Integer accountno, double diferencia); + + public void crear(Account account); + + public void update(Account account); + + public List getAccountsByEmpno(Integer empno); + + public void delete(Integer accountno); + +} diff --git a/src/main/java/com/example/hibernate/model/servicio/IEmpleadoServicio.java b/src/main/java/com/example/hibernate/model/servicio/IEmpleadoServicio.java new file mode 100644 index 0000000..e932ced --- /dev/null +++ b/src/main/java/com/example/hibernate/model/servicio/IEmpleadoServicio.java @@ -0,0 +1,10 @@ +package com.example.hibernate.model.servicio; + +import com.example.hibernate.model.Emp; +import com.example.hibernate.model.util.exceptions.InstanceNotFoundException; + +public interface IEmpleadoServicio { + public Emp find(Integer empno) throws InstanceNotFoundException; + + +} diff --git a/src/main/java/com/example/hibernate/model/util/GenericDaoHibernate.java b/src/main/java/com/example/hibernate/model/util/GenericDaoHibernate.java new file mode 100644 index 0000000..46a59ff --- /dev/null +++ b/src/main/java/com/example/hibernate/model/util/GenericDaoHibernate.java @@ -0,0 +1,89 @@ +package com.example.hibernate.model.util; + +import java.io.Serializable; +import java.lang.reflect.ParameterizedType; +import java.util.List; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import com.example.hibernate.model.util.exceptions.InstanceNotFoundException; + +/** + * Implementación xenérica do DAO en Hibernate. + * + * @author maria + */ +public class GenericDaoHibernate implements IGenericDao { + + private final Class entityClass; + private final SessionFactory sessionFactory; + + @SuppressWarnings("unchecked") + public GenericDaoHibernate(SessionFactory sessionFactory) { + // getClass(): accedemos a la clase de la instancia que extienda esta clase + // (será ProfesorDaoHibernate u XDaoHibernate) + // .getGenericSuperclass(): obtenemos el tipo de la clase madre directa: + // GenericDaoHibernate En el caso de que sea una clase parametrizada (con + // Generics),devuelve el tipo del parámetro de tipo E: ParameterizedType: + // https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getGenericSuperclass-- + // .getActualTypeArguments(): devuelve un array de los tipos de los argumentos + // que se le pasan al tipo parametrizado + // finalmente obtenemos el nombre del tipo parametrizado: que será + // Profesor + this.entityClass = (Class) ((ParameterizedType) getClass().getGenericSuperclass()) + .getActualTypeArguments()[0]; + + this.sessionFactory = sessionFactory; + } + + protected Session getSession() { + return sessionFactory.getCurrentSession(); + } + + + @Override + public void create(E entity) { + Session session = getSession(); + session.persist(entity); + } + + @Override + public E update(E entity) { + Session session = getSession(); + return session.merge(entity); + } + + @Override + public boolean exists(PK id) { + Session session = getSession(); + return session.get(entityClass, id) != null; + } + + @Override + public E find(PK id) throws InstanceNotFoundException { + Session session = getSession(); + E entity = session.get(entityClass, id); + if (entity == null) { + throw new InstanceNotFoundException(id, entityClass.getName()); + } + return entity; + } + + @Override + public void remove(PK id) throws InstanceNotFoundException { + Session session = getSession(); + E entity = session.get(entityClass, id); + if (entity == null) { + throw new InstanceNotFoundException(id, entityClass.getName()); + } + session.remove(entity); + } + + @Override + public List findAll() { + Session session = getSession(); + return session.createSelectionQuery("SELECT c FROM " + entityClass.getName() + " c", entityClass) + .getResultList(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/model/util/IGenericDao.java b/src/main/java/com/example/hibernate/model/util/IGenericDao.java new file mode 100644 index 0000000..b124877 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/util/IGenericDao.java @@ -0,0 +1,67 @@ +package com.example.hibernate.model.util; + +import java.io.Serializable; +import java.util.List; + +import com.example.hibernate.model.util.exceptions.InstanceNotFoundException; + +/** + * + * @author maria + * @param + */ +public interface IGenericDao { + // Usamos un tipo genérico para indicar que la interfaz IGenericDao tendrá un + // parámetro de cualquier tipo (clases del modelo), salvo tipos primitivos + // https://docs.oracle.com/javase/tutorial/java/generics/types.html + //Se usa un segundo tipo parametrizado para la clave primaria + + /*** + * Guarda una entidad en el sistema de persistencia + * + * @param entity + * @return la entidad con la clave primaria asignada + */ + public void create(E entity); + + /*** + * Busca en el sistema de persistencia una entidad por su clave primaria + * + * @param id + * @return la entidad si la encuentra + * @throws InstanceNotFoundException si no encuentra la entidad + */ + public E find(PK id) throws InstanceNotFoundException; + + /*** + * Comprueba si existe la entidad con ese id como clave primaria + * + * @param id + * @return true si se ha encontrado, false en caso contrario. + */ + public boolean exists(PK id); + + /*** + * Elimina una entidad del sistema de persistencia + * + * @param id clave primaria para encontrar la entidad + * @throws InstanceNotFoundException si no encuentra la entidad + */ + public void remove(PK id) throws InstanceNotFoundException; + + /** + * Obtiene una lista de todas las entidades en el sistema persistente + * + * @return + */ + public List findAll(); + + /** + * Actualiza una entidad del sistema de persistencia + * @param entidad a actualizar + * @return entidad actualizada y persistente + */ + public E update(E entity); + + +} \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/model/util/OperacionHibernate.java b/src/main/java/com/example/hibernate/model/util/OperacionHibernate.java new file mode 100644 index 0000000..be050f7 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/util/OperacionHibernate.java @@ -0,0 +1,6 @@ +package com.example.hibernate.model.util; + +@FunctionalInterface +public interface OperacionHibernate { + public R ejecutar() throws Exception; +} \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/model/util/TransactionManager.java b/src/main/java/com/example/hibernate/model/util/TransactionManager.java new file mode 100644 index 0000000..5bbf637 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/util/TransactionManager.java @@ -0,0 +1,28 @@ +package com.example.hibernate.model.util; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; + +public class TransactionManager { + + private final SessionFactory sessionFactory; + + public TransactionManager(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + public R ejecutar(OperacionHibernate operacion) { + Transaction tx = null; + try { + Session session = sessionFactory.getCurrentSession(); + tx = session.beginTransaction(); + R resultado = operacion.ejecutar(); + tx.commit(); + return resultado; + } catch (Exception e) { + if (tx != null) tx.rollback(); + throw new RuntimeException("Error en la transacción", e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/model/util/exceptions/InstanceNotFoundException.java b/src/main/java/com/example/hibernate/model/util/exceptions/InstanceNotFoundException.java new file mode 100644 index 0000000..1c19301 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/util/exceptions/InstanceNotFoundException.java @@ -0,0 +1,35 @@ +package com.example.hibernate.model.util.exceptions; + + + + +/** + * + * @author maria + */ +public class InstanceNotFoundException extends Exception { + + + private Object key; + private String className; + + private static final String DEFAULT_MSG = "Instance not found"; + + public InstanceNotFoundException( Object key, + String className) { + + super(DEFAULT_MSG + " (key = '" + key + "' - className = '" + + className + "')"); + this.key = key; + this.className = className; + + } + + public Object getKey() { + return key; + } + + public String getClassName() { + return className; + } +} diff --git a/src/main/java/com/example/hibernate/util/HibernateUtil.java b/src/main/java/com/example/hibernate/util/HibernateUtil.java new file mode 100644 index 0000000..ea32e11 --- /dev/null +++ b/src/main/java/com/example/hibernate/util/HibernateUtil.java @@ -0,0 +1,68 @@ +package com.example.hibernate.util; + +import org.hibernate.SessionFactory; +import org.hibernate.boot.registry.StandardServiceRegistry; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; + +import com.example.hibernate.model.AccMovement; +import com.example.hibernate.model.Account; +import com.example.hibernate.model.Dept; +import com.example.hibernate.model.Emp; +import com.example.hibernate.model.Project; + +public class HibernateUtil { + + private static HibernateUtil instance; + private static SessionFactory sessionFactory; + private static StandardServiceRegistry serviceRegistry; + + // Private constructor to prevent external instantiation + private HibernateUtil() { + try { + // Automatically reads hibernate.properties or hibernate.cfg.xml from classpath + serviceRegistry = new StandardServiceRegistryBuilder() + .build(); + + // Build SessionFactory using the service registry + sessionFactory = new org.hibernate.boot.MetadataSources(serviceRegistry) + .addAnnotatedClass(AccMovement.class) + .addAnnotatedClass(Account.class) + .addAnnotatedClass(Dept.class) + .addAnnotatedClass(Emp.class) + .addAnnotatedClass(Project.class) + + .buildMetadata() + .buildSessionFactory(); + } catch (Exception ex) { + throw new ExceptionInInitializerError("Failed to create SessionFactory: " + ex); + } + } + + // Singleton accessor method + public static HibernateUtil getInstance() { + if (instance == null) { + instance = new HibernateUtil(); + } + return instance; + } + + // Get the SessionFactory + public SessionFactory getSessionFactory() { + return sessionFactory; + } + + // Shutdown Hibernate and clean up resources + // Destrue os rexistros de servizo e pecha o SessionFactory + public static void shutdown() { + if (serviceRegistry != null) { + StandardServiceRegistryBuilder.destroy(serviceRegistry); + } + } + + // Cerra a sesión e limpa os recursos + public void close() { + if (sessionFactory != null) { + sessionFactory.close(); + } + } +} diff --git a/src/main/resources/hibernate.properties b/src/main/resources/hibernate.properties new file mode 100644 index 0000000..f4b0b3f --- /dev/null +++ b/src/main/resources/hibernate.properties @@ -0,0 +1,17 @@ +# Database connection settings +hibernate.connection.url=jdbc:mysql://localhost:3306/empresa +hibernate.connection.driver_class=com.mysql.cj.jdbc.Driver +hibernate.connection.username=user_empresa +hibernate.connection.password=password + +# Echo all executed SQL to console +hibernate.show_sql=true +hibernate.format_sql=true +hibernate.highlight_sql=true + +hibernate.default_schema=empresa +hibernate.dialect=org.hibernate.dialect.MySQLDialect +hibernate.hbm2ddl.auto=update +hibernate.default_catalog=empresa + +hibernate.current_session_context_class=thread diff --git a/src/main/resources/scripts/mariadb/1_scripts_empresa.sql b/src/main/resources/scripts/mariadb/1_scripts_empresa.sql new file mode 100644 index 0000000..6fd463a --- /dev/null +++ b/src/main/resources/scripts/mariadb/1_scripts_empresa.sql @@ -0,0 +1,131 @@ +-- Select the database only if it doesn't already exist +CREATE DATABASE IF NOT EXISTS empresa; + +-- Switch to empresa database +USE empresa; + +-- Create the DEPT table only if it doesn't already exist +CREATE TABLE IF NOT EXISTS DEPT ( + DEPTNO INT AUTO_INCREMENT PRIMARY KEY, + DNAME VARCHAR(20), + LOC VARCHAR(20) +); + +-- Create the EMP table only if it doesn't already exist +CREATE TABLE IF NOT EXISTS EMP ( + EMPNO INT AUTO_INCREMENT PRIMARY KEY, + ENAME VARCHAR(20), + JOB VARCHAR(20), + MGR INT, + HIREDATE DATE, + SAL DECIMAL(15,2), + COMM DECIMAL(15,2), + DEPTNO INT, + FOREIGN KEY (MGR) REFERENCES EMP(EMPNO), + FOREIGN KEY (DEPTNO) REFERENCES DEPT(DEPTNO) +); + +-- Switch to empresa database +USE empresa; + +-- Insert values into the DEPT table with specific DEPTNO values +INSERT INTO DEPT (DEPTNO, DNAME, LOC) VALUES + (10, 'ACCOUNTING', 'NEW YORK'), + (20, 'RESEARCH', 'DALLAS'), + (30, 'SALES', 'CHICAGO'), + (40, 'OPERATIONS', 'BOSTON'); + +-- Insert values into the EMP table with specific EMPNO values +INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES + (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000, NULL, 10), + (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, NULL, 20), + (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, NULL, 10), + (7788, 'SCOTT', 'ANALYST', 7566, '1982-12-09', 3000, NULL, 20), + (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, NULL, 20), + (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, NULL, 30), + (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, NULL, 20), + (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30), + (7521, 'WARD', 'SALESMAN', 7698, '1981-02-20', 1250, 500, 30), + (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30), + (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500, 0, 30), + (7876, 'ADAMS', 'CLERK', 7788, '1983-01-12', 1100, NULL, 20), + (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, NULL, 30), + (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, NULL, 10); + + +-- Seleccionar la base de datos +USE empresa; + +-- Crear tabla ACCOUNT solo si no existe +CREATE TABLE IF NOT EXISTS ACCOUNT ( + ACCOUNTNO INT NOT NULL AUTO_INCREMENT, + EMPNO INT NOT NULL, + AMOUNT DECIMAL(19, 4) NOT NULL, + PRIMARY KEY (ACCOUNTNO), + FOREIGN KEY (EMPNO) REFERENCES EMP(EMPNO) +) ENGINE=InnoDB; + +-- Eliminar restricción si existe y crear tabla ACC_MOVEMENT solo si no existe +CREATE TABLE IF NOT EXISTS ACC_MOVEMENT ( + ACCOUNT_MOV_ID INT NOT NULL AUTO_INCREMENT, + ACCOUNT_ORIGIN_ID INT NOT NULL, + ACCOUNT_DEST_ID INT NOT NULL, + AMOUNT DECIMAL(19, 4) NOT NULL, + DATETIME DATETIME NOT NULL, + PRIMARY KEY (ACCOUNT_MOV_ID), + FOREIGN KEY (ACCOUNT_ORIGIN_ID) REFERENCES ACCOUNT(ACCOUNTNO), + FOREIGN KEY (ACCOUNT_DEST_ID) REFERENCES ACCOUNT(ACCOUNTNO) +) ENGINE=InnoDB; + + +USE empresa; + +-- Insertar en la tabla ACCOUNT para cada empleado que no tenga una cuenta +INSERT INTO ACCOUNT (EMPNO, AMOUNT) +SELECT DISTINCT EMPNO, 1000 + IFNULL(COMM, 0) +FROM EMP +WHERE EMPNO NOT IN (SELECT DISTINCT EMPNO FROM ACCOUNT); + + +USE empresa; + +CREATE TABLE IF NOT EXISTS PROJECT ( + PROJNO INT AUTO_INCREMENT NOT NULL, + PROJNAME VARCHAR(50) NOT NULL, + PRIMARY KEY (PROJNO) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS PROJECT_EMP ( + PROJECTNO INT NOT NULL, + EMPNO INT NOT NULL, + PRIMARY KEY (PROJECTNO, EMPNO), + FOREIGN KEY (EMPNO) REFERENCES EMP(EMPNO) ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (PROJECTNO) REFERENCES PROJECT(PROJNO) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + + +use empresa; +INSERT INTO PROJECT (PROJNAME) VALUES +('Desenvolvemento de Software Libre'), +('Inteligencia Artificial para Empresas'), +('Plataforma de Comercio Electrónico'), +('Seguridade Informática Avanzada'), +('Automatización con Internet das Cousas'); + + +INSERT INTO PROJECT_EMP (PROJECTNO, EMPNO) VALUES +-- Primeiro proxecto: Desenvolvemento de Software Libre +(1, 7369), (1, 7566), (1, 7788), + +-- Segundo proxecto: Intelixencia Artificial para Empresas +(2, 7521), (2, 7839), (2, 7902), + +-- Terceiro proxecto: Plataforma de Comercio Electrónico +(3, 7654), (3, 7499), (3, 7782), + +-- Cuarto proxecto: Seguridade Informática Avanzada +(4, 7698), (4, 7844), + +-- Quinto proxecto: Automatización con Internet das Cousas +(5, 7876), (5, 7934); + diff --git a/src/main/resources/scripts/mariadb/2_create_user.sql b/src/main/resources/scripts/mariadb/2_create_user.sql new file mode 100644 index 0000000..da33752 --- /dev/null +++ b/src/main/resources/scripts/mariadb/2_create_user.sql @@ -0,0 +1,3 @@ +CREATE USER 'user_empresa'@'localhost' IDENTIFIED BY 'password'; +GRANT ALL PRIVILEGES ON empresa.* TO 'user_empresa'@'localhost'; +FLUSH PRIVILEGES; \ No newline at end of file