One to One Weak Entity Mapping JPA - java

I have a Entity Class
#Entity
Class Search
{
#Id
private Long SearchID;
private String Type;
}
and another Entity Class ( SearchResults which is a weak Entity that depends on Search Class for its Primary Key
#Entity
Class SearchResults
{
#???
private Long SearchID;
}
What annotation should i use to assign "SearchID" of "Search" Entity class as my primary key in my weak Entity " SearchResults"

Using the JPA concept of Shared Primary Key, you can map your relationship as follows:
Your main class:
#Entity
public class Search {
#Id
private Long searchID;
private String type;
}
Derived Identifier with Single Attribute
#Entity
public class SearchResults {
#Id
#OneToOne
#JoinColumn(name = "SEARCHID")
private Search search;
}
Deriver Identifier with Shared Mappings
#Entity
public class SearchResults {
#Id
private Long searchID;
#MapsId
#OneToOne
#JoinColumn(name = "SEARCHID")
private Search search;
}
Full article here: http://vard-lokkur.blogspot.com.br/2014/05/onetoone-with-shared-primary-key.html

SearchResult does not have to be an entity.
While it can be mapped as an Enity with a shared PK as suggested in the other answer, as a Weak entity it cannot exist independently of its associated Search and so can be mapped as an Embeddable.
https://en.wikibooks.org/wiki/Java_Persistence/Embeddables
#Entity
public class Search
{
#Id
private Long SearchID;
private String Type;
#ElementCollection
#CollectionTable(....)
private Set<SearchResults> results;
}
#Embeddable
public class SearchResults
{
//does not need an Id
//other fields
}

Related

Search JPA complex object for nested object based on its value

Lets assume we have a complex JPA relation, a fraction of which looks like this:
#MappedSuperclass
public class DiffEntity {
private String diffId;
public DiffEntity() {
this.diffId = UUID.randomUUID().toString();
}
//...
}
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public class ParentEntity extends DiffEntity {
#Id
#GeneratedValue
private long id;
#Column
private String name;
//...
}
#Entity
public class Construct extends ParentEntity {
#Column
private String variable;
#OneToMany(mappedBy = "construct", cascade = CascadeType.ALL)
private List<Partconstruct> partconstructs;
//...
}
#Entity
public class Partconstruct extends ParentEntity {
#OneToMany(mappedBy = "partconstruct", cascade = CascadeType.ALL)
private List<Field> fields;
#OneToMany(mappedBy = "partconstruct", cascade = CascadeType.ALL)
private List<Hardparameter> hardparameters;
#ManyToOne
#JoinColumn(name = "construct_id")
private Construct construct;
//...
}
#Entity
public class Field extends ParentEntity {
#Column
private int fieldSize;
#ManyToOne
#JoinColumn(name = "partconstruct_id")
private Partconstruct partconstruct;
//...
}
#Entity
public class Hardparameter extends ParentEntity {
#Column
private String value;
#ManyToOne
#JoinColumn(name = "partConstruct_Id")
private Partconstruct partConstruct;
//...
}
We are concerned with Construct type objects. Construct is deeply cloned and persisted, having all its nested objects on the object graph being cloned too and getting a new Id (primary key). On every clone the diffId (from DiffEntity entity) stays the same (it serves the purpose of correlating objects for a diffing feature).
How would it be possible to search and get a reference for a specific DiffEntity given we have the below:
a reference to the Construnct instance
type of the nested object
diffId we are after.
I have tried different versions of object graph traversers with reflection, which will work for a small in size Construct object, but once it becomes too big performance is very slow.
Is there any magic on the entity manager itself to achieve that ?

Will the findAll function of Spring Data JPA repository work if the entites are related as many to one or one to one or any such association?

Here is how the entity class looks like
#Entity
public class IndustryCode {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String industryName;
#OneToMany(mappedBy="industryCode")
private Set<CarrierCodes> industryCodes;
#Entity
public class TechCode {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String techName;
#OneToMany(mappedBy="techCode")
private Set<CarrierCodes> techCodes;
#Entity
public class CarrierCodes {
#EmbeddedId
private CarrierCodesId id = new CarrierCodesId();
#ManyToOne
#MapsId("techCodeId")
private TechCode techCode;
#ManyToOne
#MapsId("industryCodeId")
private IndustryCode industryCode;
#SuppressWarnings("serial")
#Embeddable
public class CarrierCodesId implements Serializable {
private Long industryCodeId;
private Long techCodeId;
#Entity
public class Register {
#Id
private Long mobileNumber;
#ManyToOne
// optional but nice to have consistent names
#JoinColumns({
#JoinColumn(name="industryCode_id", referencedColumnName="industryCode_id"),
#JoinColumn(name="techCode_id", referencedColumnName="techCode_id")
)
private CarrierCodes carrierCodes;
}
public class RegisterRepository extends JPARepository<Register,mobileNumber>{
}
My question is if I run findAll on Register table will I get the data for other related tables as well?
I mean using findAll(), will I get a List from which I can take Register obj and use .getCarrierCode().getIndustryCode().getIndustryName() to get industry name corresponding to carrierCode value in Register table

JPA #JoinColumn one to many bi-directional relationship with a composite key as FK

I have been scratching my head over this for weeks now and I have no idea how to work my way around it.
I have two tables:
Author (author_code, author_number, author_name) author_code and author_number are primary keys
Title (author_code, title_code, sequence, title_desc) title_code and sequence are primary keys
Code:
#Entity
#IdClass(AuthorPK.class)
#Table(name="Author")
public class Author implements Serializable {
#Id
#Column(name="author_code")
private long authorCode;
#Id
#Column(name="author_number")
private String authorNumber;
#Column(name="author_name")
private String authorName;
//bi-directional many-to-one association to Title
#OneToMany(mappedBy="author")
private List<Title> titles;
//getter setters
}
public class AuthorPK implements Serializable {
private long authorCode;
private String authorNumber;
//getter equals() hashCode()
}
#Entity
#IdClass(TitlePK.class)
#Table(name="Title")
public class Title implements Serializable {
#Id
#Column(name="title_code")
private long titleCode;
#Id
#Column(name="sequence")
private long sequence;
#Column(name="title_desc")
private String titleDesc;
//bi-directional many-to-one association to Author
#ManyToOne
#JoinColumns({
#JoinColumn(name="author_code", referencedColumnName="author_code"),
#JoinColumn(name="author_number", referencedColumnName="author_number")
})
private Author author;
//getters setters
}
public class TitlePK implements Serializable {
private long titleCode;
private long sequence;
//getter equals() hashcode()
}
I need to link the two entities via author_code but JPA requires me to include both IDs in the #JoinColumn... it's throwing errors on my application since the source table doesn't have the other column. Is there another way for me to join these entities?

Composite Key with subclass in hibernate

I have a Class system
#Entity
abstract class System{
#Id
int systemId;
//setter and getters..
}
and which is extended by class
#Entity
class PhysicalSystem extends System
{
#Id
int place;
//setter and getters..
}
in need to make the composite key by using the systemId and place
how can i do this.. if i have #Id in both class its throws exception
Initial SessionFactory creation failed.java.lang.ClassCastException: org.hibernate.mapping.JoinedSubclass cannot be cast to org.hibernate.mapping.RootClass
How can i solve this?
Tables:
System{
systemid PK
systemName
}
PhysicalSystem
{
systemId PK
locationId PK
}
In your case, maybe the best solution is a OneToOne mapping:
#Entity
public class PhysicalSystem implements Serializable {
#EmbeddedId
private PhysicalSystemKey key;
#JoinColumns({JoinColumn(name = "key.systemId", referencedColumnName = "ctvId"})
#OneToOne(mappedBy = "physicalSystem")
private System system;
// ...
}
#Embeddable
public class PhysicalSystemKey {
private Long systemId;
private Long locationId;
// ...
}
#Entity
public class System implements Serializable {
#Id
private Long systemId;
#OneToOne(mappedBy = "system")
private PhysicalSystem physicalSystem;
}

JPA many to many with extra column

I have a following problem that I need to solve.
The core issues is that I want to add additional column into JoinTable for ManyToMany relation in JPA. In my case I have following entities.
The Topic is a simple entity which has many RemoteDocument's (one RemoteDocument may be refered by many Topic's, hence it should be ManyToMany relation). Also RemoteDocument entity is read only because it may be read only from Oracle Materialized View moreover any altering of this Materialized View is forbidden. So I want to store order of RemoteDocuments related to some Topic. In fact I can do something like that with additional entity:
#Entity
public class Topic {
#Id
private Long id;
#Basic
private String name;
#OneToMany
private Set<TopicToRemoteDocument> association;
}
#Entity
public class RemoteDocument {
#Id
private Long id;
#Basic
private String description;
}
#Entity
public class TopicToRemoteDocument {
#OneToOne
private Topic topic;
#OneToOne
private RemoteDocument remoteDocument;
#Basic
private Integer order;
}
In this case additional entity TopicToRemoteDocument helps me to replace ManyToMany association with OneToMany and add extra field order.
But I want to have ManyToMany relation but with configured additional column in join table
Use list instead of set, together with the #OrderColumn annotation and JPA will automatically take care of the order:
#MappedSuperclass
public class BaseEntity{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
public Long getId(){
return id;
}
public void setId(final Long id){
this.id = id;
}
}
#Entity
public class Topic extends BaseEntity{
#ManyToMany(mappedBy = "topics")
#OrderColumn
private List<Document> documents = new ArrayList<Document>();
public List<Document> getDocuments(){
return documents;
}
public void setDocuments(final List<Document> documents){
this.documents = documents;
}
}
#Entity
public class Document extends BaseEntity{
#ManyToMany
#OrderColumn
private List<Topic> topics = new ArrayList<Topic>();
public List<Topic> getTopics(){
return topics;
}
public void setTopics(final List<Topic> topics){
this.topics = topics;
}
}
Generated DDL (using hibernate and HSQL):
create table Document (
id bigint generated by default as identity (start with 1),
primary key (id)
);
create table Document_Topic (
documents_id bigint not null,
topics_id bigint not null,
topics_ORDER integer not null,
documents_ORDER integer not null,
primary key (documents_id, topics_ORDER)
);
create table Topic (
id bigint generated by default as identity (start with 1),
primary key (id)
);
alter table Document_Topic
add constraint FK343B5D0B481100B2
foreign key (documents_id)
references Document;
alter table Document_Topic
add constraint FK343B5D0B558627D0
foreign key (topics_id)
references Topic;
I would try to avoid using a List unless you allow duplicates.
There is a #OrderColumn annotation that automatically does this. Have you tried it?
#Entity
public class Topic {
#Id
private Long id;
#Basic
private String name;
#OneToMany
#OrderColumn
private Set<TopicToRemoteDocument> association;
}
One technique that is useful when creating the many-to-many mapping class entity is to attribute the id's in the class along with #ManyToOne designation which makes this class act as the composite key class:
#Entity
#Table(name = "market_vendor")
public class MarketVendor implements Serializable
{
#Id
#ManyToOne
#JoinColumn(name = "market_id")
private Market market;
#Id
#ManyToOne
#JoinColumn(name = "vendor_id")
private Vendor vendor;
#Basic
#Column(name="active")
private boolean active;
public MarketVendor(Market market, Vendor vendor, boolean active)
{
this.market = market;
this.vendor = vendor;
this.active = active;
}
}
This allows you to have the composite primary key defined within the same class without having to have a separate primary key class. You also need to make the class serializable.

Categories