Search code examples
javaspringhibernatejpa

Spring Jpa entity convention of linking to other entities


I see some different implementations of linking one entity to others. For example, most Jpa with hibernate use relations annotations, for example:

@Entity
@Data
public class Employee {
   //id 
.....
   @JoinTable(...)
   @ManyToMany
   Set<Company> companies;
}

@Entity
@Data
public class Company {
   //id 
.....
   @JoinTable(...)
   @ManyToMany
   Set<Employee> employees;
}

But in some occasions, this is used:

@Entity
@Data
public class Employee {
   //id 
.....
   private Long companyId;
}

@Entity
@Data
public class Company {
   //id 
   private Long employeeId;
}

And then use @Query(value="SELECT ... FROM ... WHERE employeeId / companyId =: ....", nativeQuery = true) in respective repository interface extending JpaRepository<....> to select employees/companies with particular fk.
which one is preferred? I know lots of tutorials use the first one, but I think the second seems to be easier? That being said, is the second one even accepted in jpa annotation? Should I stick with the first annotation?


Solution

  • There is no "best approach for all cases" when it comes to computer science, it depends very much on specific details of each project.

    First of all it is important to note that your project doesn't reflect a real Many To Many relationship, one company has many employees, but can an employee bet at multiple companies at same time? makes not much sense in real world.

    I particularly use the @ManyToMany when it comes to defining this kind of relationships... I avoid at maximum using @JoinTable as it is not necessary at all, you just need to use this annotation in case you want to force a specific name for the join table or its columns, by default hibernate will name them.

    I've never seen anyone defining the data model as you made in the second example and it for sure wont be able to represent a many to many relationship

    if you put the company_id in the employee entity how do you want to represent the employee having multiple companies? it wont be mathematically possible at all

    Also, by using a long to set the foreigner key in your relationship no ORM tool in the world will be able to parse and create the entities for you, you gonna yourself need to take care of all foreigner keys, parsing and mapping of your entities since Hibernate has no way to guess that:

    private Long employeeId;
    

    represents a foreigner key that comes to reflect an id in a second table

    last but not least, it is strictly not recommendable to use @Query("anything", nativeQuery = true) unless strictly necessary. By defining your queries as native you basically killing the interoperability of DBMS that is the purpose of JPA