Proyecto backend en Java (Spring Boot) para la gestión de ofertas de trabajo (vacantes), solicitudes y usuarios. Este README se centra en explicar cómo funcionan las relaciones entre las entidades del dominio y cómo se reflejan en la base de datos.
- Java 17+
- Spring Boot (JPA/Hibernate)
- PostgreSQL
- Lombok
- Maven
La configuración principal está en src/main/resources/application.properties.
Valores por defecto en este repositorio:
- URL:
jdbc:postgresql://localhost:5432/empleos - Usuario:
postgres - Password: ``
Asegúrate de crear la base de datos empleos y configurar las credenciales si difieren.
A continuación se describen las entidades más importantes y cómo se relacionan entre sí en el código del proyecto.
- Vacantes
- Tabla:
vacantes(entidadVacantes) - Campos relevantes:
id,offerName,description,date,salary,image,featured. - Relaciones:
- ManyToOne ->
Estado(columnaestado_id): cada vacante tiene un estado (ACTIVO, INACTIVO, ...). - OneToMany ->
Solicitudes(mappedBy = "vacancy"): una vacante puede tener muchas solicitudes. En la entidadVacantesse defineprivate Set<Solicitudes> requestscon cascade ALL y orphanRemoval = true, por lo que al eliminar una vacante sus solicitudes en cascada también se eliminarán. - OneToOne ->
OfertaDetalle(columnaid_detalle): cada vacante tiene exactamente un detalle de oferta. Se usa cascade ALL y orphanRemoval; la relación es LAZY y opcional = false. - ManyToMany ->
Categoriamediante tabla intermediavacante_categoria(columnasvacante_id,categoria_id).
- ManyToOne ->
- Categoria
- Tabla:
categoria(entidadCategoria) - Campos:
id,categoryName,description. - Relaciones:
- ManyToMany (mappedBy = "categories") con
Vacantes(relación inversa).
- ManyToMany (mappedBy = "categories") con
- Solicitudes
- Tabla:
solicitudes(entidadSolicitudes) - Campos:
id,requestDate,file,comment. - Relaciones:
- ManyToOne ->
Vacantes(columnavacante_id): cada solicitud pertenece a una vacante. - ManyToOne ->
Estado(columnaestado_id): cada solicitud también tiene un estado. - Nota: la relación con
Usuariosestá comentada en el código; si se activa, una solicitud podría apuntar al usuario que aplica.
- ManyToOne ->
- OfertaDetalle
- Tabla:
oferta_detalle(entidadOfertaDetalle) - Contiene campos descriptivos como
requirements,responsibilities,benefits,location,startHour,endHour,processSelection,salary. - Relación OneToOne con
Vacantes(la columna envacantesesid_detalleque referenciaoferta_detalle.id).
- Usuarios
- Tabla:
usuarios(entidadUsuarios) - Campos importantes:
idUsuario,name,lastname,email,password,username,dateRegister,birthDate,jobTitle,phone,certifications, flags de cuenta (enabled, accountNonExpired, ...). - Relaciones:
- ManyToMany ->
Rolesmediante la tabla intermediauser_roles(columnasuser_id,role_id). - ManyToOne ->
Estado(columnaestado_id): el usuario tiene un estado.
- ManyToMany ->
- Lógica adicional: en
@PrePersistse establecedateRegistery, si elestadoes null, se asigna un estado por defectoEstadoType.ACTIVO.
- Roles y Permissions
Roles(tablaroles): tiene un camporolesEnumque indica el tipo de rol (ADMIN, USER, SuperVisor).Permission(tablapermissions): lista de permisos con camponameúnico.- Relación ManyToMany entre
RolesyPermissiondefinida mediante la tablarole_permissions. - Relación ManyToMany entre
UsuariosyRolesmedianteuser_roles.
- Estado y EstadoType
Estadocontiene un campotypede tipoEstadoType(enum con valores: ACTIVO, INACTIVO, PENDIENTE, SUSPENDIDO).Estadose usa como referencia (ManyToOne) desdeVacantes,SolicitudesyUsuarios.
- ManyToOne: se crea una columna FK en la tabla que contiene la referencia (ej.
vacante.estado_idapunta aestado.id). - OneToMany (inverso de ManyToOne): no crea tabla extra; es la vista inversa sobre la FK.
- OneToOne: la columna FK se crea en la entidad que contiene
@JoinColumn(aquívacantes.id_detalleapunta aoferta_detalle.id). - ManyToMany: se crean tablas intermedias explícitas (
vacante_categoria,user_roles,role_permissions).
- Cascades y orphanRemoval:
Vacantes.requestsusa cascade = ALL y orphanRemoval = true — elimina solicitudes relacionadas si se borra la vacante.Vacantes.detail(OneToOne) también usa cascade ALL y orphanRemoval = true — el detalle de oferta se elimina junto a la vacante.- Para ManyToMany se usan cascades limitados (MERGE, PERSIST) en
Usuarios.rolesyRoles.permissionListpara evitar eliminaciones no deseadas en tablas compartidas.
- Fetch types:
- Varias relaciones ManyToOne están en EAGER (Vacantes->Estado, Solicitudes->Vacantes, Solicitudes->Estado), lo que carga la referencia inmediatamente.
- ManyToMany en
Usuarios.rolesyRoles.permissionListestán en LAZY por defecto.
- Valores por defecto:
Usuarios.prePersist()establecedateRegister = new Date()y unEstadopor defecto si no existe.
Vacantes --< Solicitudes Vacantes --1-- OfertaDetalle
|
|--< vacante_categoria >-- Categoria
|
`-- Estado (ManyToOne)
Usuarios --< user_roles >-- Roles --< role_permissions >-- Permission `-- Estado (ManyToOne)
-
Asegura PostgreSQL en
localhost:5432con la baseempleos. -
Actualiza
src/main/resources/application.propertiessi usas otras credenciales. -
Comandos útiles (Windows):
- Empaquetar:
mvnw.cmd -DskipTests package - Ejecutar:
mvnw.cmd spring-boot:run - Ejecutar jar (después de empaquetar):
java -jar target\Empleos-Backend-0.0.1-SNAPSHOT.jar
- Empaquetar:
- La aplicación usa
spring.jpa.hibernate.ddl-auto=create-droppor defecto (enapplication.properties), lo que recrea el esquema en cada ejecución. En producción, cambia esto avalidateonone.
- Documentar endpoints en
presentation/controller(añadir ejemplos de JSON para crear Vacantes, Solicitudes y Usuarios). - Habilitar la relación Solicitudes->Usuarios si quieres llevar la relación de quién aplica a cada solicitud.
- Añadir README de API o integrar Swagger/OpenAPI para documentación automática.
Para dudas sobre el modelado o cambios en las relaciones, abre un issue o un PR y describe el caso de uso objetivo para ajustar cascades/ fetch / FK.