Hibernate Mapping Annotation without Foreign Key - spring

I have 2 tables ( Member, Department)
Member with MemberID, MemberName, DepartmentID
Department with DepartmentID, DepartmentID
Member is one to one to Department,
Department is one to many Member
Is there any ways to map them while creating the model class without using foreign key constraint in database?

Related

spring-data-jdbc: JdbcQueryCreator: Cannot query by nested entity

I'm in the process of creating a service using Spring Boot (first time using Spring). I have an entity that is identified by a triple (mission, cycle, id) in the database, this is logically the primary key.
To work around the requirement of Spring-data-jdbc of having an #Id Long primary key I have created an IDENTITY primary key and added UNIQUE constraints for these columns. In my experiment I have two tables that are keyed this way (the second has an addition column in the logical key):
CREATE TABLE IF NOT EXISTS submission_counter (
id IDENTITY NOT NULL PRIMARY KEY,
mission VARCHAR(10) NOT NULL,
cycle INTEGER NOT NULL,
proposal_id INTEGER NOT NULL,
count INTEGER NOT NULL DEFAULT 1,
UNIQUE (mission, proposal_id, cycle),
CHECK (count >= 1),
CHECK (proposal_id >= 1)
);
CREATE TABLE IF NOT EXISTS submission (
id IDENTITY NOT NULL PRIMARY KEY,
mission VARCHAR(10) NOT NULL,
cycle INTEGER NOT NULL,
proposal_id INTEGER NOT NULL,
number INTEGER NOT NULL,
CHECK (number >= 1),
CHECK (proposal_id >= 1),
UNIQUE (mission, cycle, proposal_id, number)
);
To package the key triple in the Java code I've created an embedded record for the two entity classes.
enum Mission {A, B, C}
public record SubmissionCount(int count){}
public record ProposalId(int id) {}
public record SubmissionNumber(int number) {}
public record SubmissionKey(Mission mission, Cycle cycle, ProposalId proposalId) {}
public record Submission(#Id Long id, SubmissionKey key, SubmissionNumber number) {}
public record SubmissionCounter(#Id Long id, SubmissionKey key, SubmissionCount count) {}
Previously, I had all the SubmissionKey fields inlined in the records where they are used and this all worked fine. Now, when attempting to write a query for the key I get an exception from JdbcQueryCreator
This repository definition results "Cannot query by nested entity":
public interface SubmissionRepository extends CrudRepository<Submission, Long> {
Streamable<Submission> findByKey(SubmissionKey key);
}
Caused by: java.lang.IllegalArgumentException: Cannot query by nested entity: key
at org.springframework.data.jdbc.repository.query.JdbcQueryCreator.validateProperty(JdbcQueryCreator.java:147)
I've tried writing the repository query method a number of ways. My latest attempt is based on a number of questions stating that the method name can do field navigation.
public interface SubmissionCounterRepository extends CrudRepository<SubmissionCounter, Long> {
Optional<SubmissionCounter> findByKeyMissionAndKeyCycleAndKeyProposalId(SubmissionKey key);
}
This results in
Caused by: java.lang.IllegalStateException: Query method expects at least 2 arguments but only found 1. This leaves an operator of type SIMPLE_PROPERTY for property key.cycle unbound.
at org.springframework.data.relational.repository.query.RelationalQueryCreator.throwExceptionOnArgumentMismatch(RelationalQueryCreator.java:126)
at org.springframework.data.relational.repository.query.RelationalQueryCreator.validate(RelationalQueryCreator.java:110)
at org.springframework.data.jdbc.repository.query.JdbcQueryCreator.validate(JdbcQueryCreator.java:117)
If I were hand rolling everything I would put the (mission, cycle, proposal_id) triple only in the submission_counter table and join that with the submission for reads.
Is there a better way to do this with Spring? Can I do field navigation using #Query and named parameters?
Circling back to this after a few days, the issue was the missing #Embedded annotation on the SubmissionKey element.
Added #Embedded like this solved the issues:
public record Submission(#Id Long id, #Embedded(onEmpty = Embedded.OnEmpty.USE_EMPTY) SubmissionKey key, SubmissionNumber number) {}
public record SubmissionCounter(#Id Long id, #Embedded(onEmpty = USE_EMPTY) SubmissionKey key, SubmissionCount count) {}
This allows me to define findByKey methods on my repository interfaces and the queries are correctly derived:
public interface SubmissionRepository extends CrudRepository<Submission, Long> {
Streamable<Submission> findByKey(SubmissionKey key);
}
public interface SubmissionCounterRepository extends CrudRepository<SubmissionCounter, Long> {
Optional<SubmissionCounter> findByKey(SubmissionKey key);
}
I think the error saying "Cannot Query by nested entity" meant that Spring JDBC had concluded that SubmissionKey was a separate entity nested inside the Submission entity. Obvious in hindsight.

Which entity class in Spring Boot should have cascade functionality?

I have an Employee entity class which has a one to many relationship with Skills entity class.
Should we specify cascade in Employee class or in Skills class to achieve the below mentioned conditions
An entry in employee might not have an entry in skills
An entry in employee might have multiple entries in skills
If we delete employee then the corresponding skills of the employee should also be deleted
Map entities like below will fulfill the requirements.
In Employee entity :
#OneToMany(mappedBy="employee",cascade = CascadeType.ALL,fetch=FetchType.LAZY)
private Set<Skill> skills;
In Skill Entity :
#ManyToOne
private Employee employee;
An entry in employee might have multiple entries in skills -- #OneToMany will do this.
If we delete employee then the corresponding skills of the employee should also be deleted --- cascade all will do this.

Spring JPA one to many

I have two entities :
#Entity
#Table(name="Registration")
public class Registration{
#Id
private UUID uuid;
#OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE}, fetch = FetchType.LAZY)
#JoinColumn(name="registration", nullable = false)
private List<Payment> payment;
}
#Entity
#Table(name="Payment")
public class Payment {
#Id
private UUID uuid;
/*#ManyToOne(targetEntity = Registration.class) <-- MappingException: Repeated column in mapping for entity
private Registration registration;*/
}
This entities create two tables :
TABLE `registration` (
`uuid` binary(16) NOT NULL,
PRIMARY KEY (`uuid`))
TABLE `payment` (
`uuid` binary(16) NOT NULL,
`registration` binary(16) NOT NULL,
PRIMARY KEY (`uuid`),
CONSTRAINT `FK_jgemihcy9uethvoe3l7mx2bih` FOREIGN KEY (`registration`) REFERENCES `registration` (`uuid`))
I'm using Rest Service. I can access to
registration.payment
but not
payment.registration
why ? I need a relation oneToMany bidirectionnal ?
Yes, you need to add the payment.registration #ManyToOne relationship if you use it in your code.
Take into account that JPA allows you to map a SQL database model to an object oriented one. Once you have the mapping between your objects and your database, you always work at the object level. That's why, although you have the relationship in the database, your Payment object doesn't know anything about it unless you map it to an attribute.
Of course it applies when you are using you data model objects or performing JPQL or Criteria queries. If you use native queries you have access to the database model as it is.

value of the foreign key as null in spring mvc hibernet using postgresql

I am using spring mvc hibernate with postgresql.I have created two tables employee and accounts in which there is one to many mapping from employee to accounts,and the employee id is passed as the foreign key to accounts table, but i think the id is not generating. In the database table is generated of accounts table with the foriegn key as the employee id which is the primary key of the employee table, but with null value.
for table generation
#GeneratedValue(strategy = GenerationType.IDENTITY)

Entity Framework 4.2 One to many relationship

I have 2 tables in an existing database:
Table1
[Key] public int Id {get; set;}
public int CustomerID {get; set;}
List<Table2> Table2Items {get; set;}
....
Table2
[Key] public int Id {get; set;}
public int customerid {get; set;}
Table1 Table1Item {get; set;}
...
I want to create a one-to-many relationship, such that each record in table1 can have many associated records in table2.
Its normally straight forward using the primary key field in table1 which matches the foreign key field (customerid) in table 2.
But I want to relate the 2 tables based on the CustomerID in table1 with the customerid in table2.
The following appears to relate the 2 tables by using the customerid field in table2 with the primary key in table1, which is not what I require.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Table1>()
.HasMany<Table2>(s => s.Table2Items)
.WithRequired(s => s.Table1Item)
.HasForeignKey(s => s.customerid);
}
How can I modify the code shown above to fit my requirements.
What you are trying to achieve is impossible with current version of Entity Framework. Quoting from https://stackoverflow.com/a/7022799/337294:
It is not possible. Relations in EF follows exactly same rules as in the database. It means that principal table must have unique identifier which is referenced by dependent table. In case of database the identifier can be either primary key or unique column(s) of principal table. Otherwise it is not valid relation.
And since Entity Framework does not support unique indexes yet (despite strong demand in their Feature Suggestion page), it has to be the Id property of your Table1 class.

Resources