how does lazy loading work - java

I have 2 classes.Video and VideoLinks.VideoLinks related to Video by ManyToOne and LazyLoading.Lazy loading means when i need Video then Video will be fetched.
i select VideoLinks and then sleep 10 seconds.i change Video title in database and after 10 seconds application prints related Video title.But this title is not changed title but old title.
Video:
#Entity
#Table(name = "video")
#XmlRootElement
public class Video implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Column(name = "title")
private String title;
#Column(name = "url")
private String url;
#Lob
#Column(name = "description")
private String description;
#Column(name = "date")
#Temporal(TemporalType.TIMESTAMP)
private Date date;
#Column(name = "focused_word")
private String focusedWord;
#Column(name = "tags")
private String tags;
#Column(name = "seo_title")
private String seoTitle;
#Column(name = "seo_description")
private String seoDescription;
#Column(name = "category_id")
private String categoryId;
#Column(name = "slug")
private String slug;
#Column(name = "body")
private String body;
#Column(name = "thumb")
private String thumb;
#Column(name = "body_html")
private String bodyHtml;
public Video() {
}
public Video(Integer id) {
this.id = id;
}
//getter-setters
}
VideoLinks:
#Entity
#Table(name = "video_links")
#XmlRootElement
public class VideoLinks implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Column(name = "url")
private String url;
#Column(name = "text")
private String text;
#Basic(optional = false)
#Column(name = "working")
private boolean working;
#JoinColumn(name = "video_id", referencedColumnName = "id")
#ManyToOne(optional = false, fetch = FetchType.LAZY)
private Video videoId;
public VideoLinks() {
}
public VideoLinks(Integer id) {
this.id = id;
}
public VideoLinks(Integer id, boolean working) {
this.id = id;
this.working = working;
}
//getter-setters
}
Main:
public static void main(String[] args) {
VideoServiceInter serviceVideo = new VideoService();
VideoLinks videoLinks = serviceVideo.getVideoLinks(15);
System.out.println("i fetched VideoLinks but not Video yet");
try {
Thread.sleep(10000);//at this waiting time i change title in database
} catch (InterruptedException ex) {
LOG.log(Level.SEVERE, null, ex);
}
System.out.println(vl.getVideoId().getTitle());
}

Related

Spring Data JPA Non-key field references in Spring Data JPA

EntityDiagram How to Event(id) refererences to CurriculumVitae(event_id) and FamilyMember(id) refererences to CurriculumVitae(family_member_id)
My code is :
#Getter
#Setter
#ToString
#Data
#Entity
#Table(name = "CurriculumVitaes")
public class CurriculumVitae implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "identity_card_number")
private String identityCardNumber;
#Column(name = "place_for_identity_cards")
private String placeForIdentityCards;
#Column(name = "phone_number")
private String phoneNumber;
#Column(name = "ethnic")
private String ethnic;
#Column(name = "religion")
private String religion;
#Column(name = "family_composition_after_land_reform")
private String familyCompositionAfterLandReform;
#Column(name = "family_member")
private String familyMember;
#Column(name = "education_level")
private String educationLevel;
#Column(name = "language")
private String language;
#Column(name = "qualification")
private String qualification;
#Column(name = "type_of_education")
private String typeOfEducation;
#Column(name = "specialized_training")
private String specializedTraining;
#Column(name = "health_situation")
private String healthSituation;
#Column(name = "tall")
private String tall;
#Column(name = "weight")
private String weight;
#Column(name = "occupation_or_qualification")
private String occupationOrQualification;
#Column(name = "ranks")
private String rank;
#Column(name = "current_salary")
private String currentSalary;
#Column(name = "date_of_enlistment")
private Date dateOfEnlistment;
#Column(name = "date_of_demobilization")
private Date dateOfDemobilization;
#Column(name = "reason")
private String reason;
#OneToMany(mappedBy = "curriculumVitae", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#EqualsAndHashCode.Exclude
#ToString.Exclude
#JsonIgnore
private Collection<Event> event;
#OneToMany(mappedBy = "curriculumVitae", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#EqualsAndHashCode.Exclude
#ToString.Exclude
#JsonIgnore
private Collection<FamilyMember> familyMemberList;
}
But FamilyMembers(curriculum_vitae_id) references to CurriculumVitae(id)*
#Getter
#Setter
#ToString
#Data
#Entity
#Table(name = "FamilyMembers")
public class FamilyMember implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "name")
private String name;
#Column(name = "occupation")
private String occupation;
#Column(name = "august_revolution")
private String augustRevolution;
#Column(name = "resistance_war_against_French_colonialism")
private String resistanceWarAgainstFrenchColonialism;
#Column(name = "activities_from_1955")
private String activitiesFrom1955;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "curriculum_vitae_id", referencedColumnName = "family_member_id")
#EqualsAndHashCode.Exclude
#ToString.Exclude
private CurriculumVitae curriculumVitae;
}

Empty List between ManyToMany relationship

I have two entities,Client and Product ,and they have a relation #ManyToMany, when I do a POST to create a Client with a Product, I recive a empty list of Produtcs.
public class Produto implements Serializable {
private static final long serialVersionUID = -6381222920639794489L;
#Id
#Column(name = "id", nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "descricao")
private String descricao;
#Column(name = "preco")
private Float preco;
#ManyToMany
#JoinTable(name = "produto_cliente",
joinColumns = #JoinColumn(name = "cliente_fk"),
inverseJoinColumns = #JoinColumn(name = "produto_fk"))
private List<Cliente> clientId;
}
public class Cliente implements Serializable {
private static final long serialVersionUID = -1195126015856369746L;
#Id
#Column(name = "id", nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "nome")
private String nome;
#Column(name = "cpf")
private String cpf;
#ManyToMany(mappedBy = "clientId")
private List<Produto> produtos;
}
The list of products
The list os clients after I created and added the product

delete call stuck for forever in a Many to One Relationship

Trying to run a delete query on a many-one relationship. But sometime it's stuck for a while when the count of row delete is more then ~50.
Repository:
#Repository
public interface TransitItemRepository extends JpaRepository<TransitItemsMapping, UUID> {
#Modifying
#Transactional
#Query(value="delete from TransitItemsMapping t where t.grouping_form_id=:groupingFormId",nativeQuery = true)
void deleteByGroupingFormId(#Param("groupingFormId") UUID groupingFormId);
}
Domain:TransitItemsMapping.java
#Data
#Entity
#Table(name = "TransitItemsMapping")
public class TransitItemsMapping implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "uuid", strategy = "uuid2")
#GeneratedValue(generator = "uuid")
#Column(name = "transit_Item_id",unique = true, nullable = false)
private UUID transitItemId;
#ToString.Exclude
#JsonManagedReference
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "grouping_form_id")
//#OnDelete(action = OnDeleteAction.CASCADE)
private GroupingForm groupingForm;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(referencedColumnName = "dim_Item_ID",name = "item_id")
private Item item;
#Column(name ="item_relationship_id", insertable = false,updatable = false)
private String itemRelationshipId;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "item_relationship_id",referencedColumnName = "dim_item_relationship_id")
private VendorFactoryItem vendorFactoryItem;
#Column(name = "edam_id")
private String edamId;
#Column(name = "model_number")
private String modelNumber;
#Column(name = "description")
private String description;
#Column(name = "packaging_details")
private String packagingDetails;
#Column(name = "packaging_method")
private String packagingMethod;
#Column(name = "is_side_stack")
private String isSideStack;
#Column(name = "quantity")
private Integer quantity;
#Column(name = "dimensions")
private String dimensions;
#Column(name = "product_net_weight")
private String productNetWeight;
#Column(name = "plastic_bag_ind")
private String plasticBagInd;
#Column(name = "insertion_order")
private Integer insertionOrder;
#Column(name = "comments")
private String comments;
#Column(name = "item_unique_id")
private String itemUniqueId;
#Column(name = "itm_pak_qty")
private Integer itemPackQuantity;
}
GroupingForm.java
#Setter
#Getter
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode
#Entity
#Table(name = "GroupingForm")
public class GroupingForm implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "uuid", strategy = "uuid2")
#GeneratedValue(generator = "uuid")
#Column(name = "grouping_form_id",unique = true, nullable = false)
private UUID groupingFormId;
#Column(name = "grouping_form_name")
private String groupingFormName;
#Column(name = "vid")
private String vid;
#Column(name = "vendor_name")
private String vendorName;
#Column(name = "hovbu")
private String hovbu;
#Column(name = "fid")
private String fid;
#Column(name = "factory_name")
private String factoryName;
#Column(name = "item_count")
private Integer itemCount;
#CreationTimestamp
#Column(name = "creation_date")
private Timestamp creationDate;
#Column(name = "created_by")
private String createdBy;
#UpdateTimestamp
#Column(name = "modified_date")
private Timestamp modifiedDate;
#Column(name = "modified_by")
private String modifiedBy;
#Column(name = "product_engineer")
private String productEngineer;
#Column(name = "status")
private String status;
#Column(name = "sourcing_type")
private String sourcingType;
#Column(name = "total_comments")
private Integer totalComments;
#Column(name = "factory_name_chinese")
private String factoryNameChinese;
#Column(name = "grouping_form_type")
private String groupingFormType;//to save as Product/transit/Product_transit
#Column(name = "ref_id")
private String refId;
#JsonBackReference
#OneToMany(mappedBy = "groupingForm", cascade = CascadeType.ALL)
private List<ProductItemsMapping> productItems = new ArrayList<>();
#JsonBackReference
#OneToMany(mappedBy = "groupingForm", cascade = CascadeType.ALL)
private List<TransitItemsMapping> transitItems = new ArrayList<>();
#Column(name = "pdf_status")
private String pdfStatus;
public GroupingForm(UUID groupingFormId,String groupingFormName, String vid, String vendorName, String hovbu,
String fid, String factoryName, String status, String sourcingType, Integer totalComments,
Date creationDate, String createdBy, Date modifiedDate, String modifiedBy, String productEngineer,
Integer itemCount, String groupingFormType, String refId, String factoryNameChinese) {
this.groupingFormId = groupingFormId;
this.groupingFormName = groupingFormName;
this.vid = vid;
this.vendorName = vendorName;
this.hovbu = hovbu;
this.fid = fid;
this.factoryName = factoryName;
this.status = status;
this.sourcingType = sourcingType;
this.totalComments = totalComments;
this.creationDate = creationDate!=null?new Timestamp(creationDate.getTime()):null;
this.createdBy = createdBy;
this.modifiedDate = modifiedDate!=null?new Timestamp(modifiedDate.getTime()):null;
this.modifiedBy = modifiedBy;
this.productEngineer = productEngineer;
this.itemCount = itemCount;
this.groupingFormType = groupingFormType;
this.refId = refId;
this.factoryNameChinese = factoryNameChinese;
}
}
Service: methods which already annotated with #Transactional
private void updateTransitItem(GroupingCardsDto groupingCardsDto, GroupingForm groupingForm) {
transitItemRepository.deleteByGroupingFormId(groupingCardsDto.getGroupingFormDto().getGroupingFormId());
groupingFormService.saveTransitItems(groupingCardsDto.getGroupingFormDto(), groupingForm);
}
when I am running eclipse in debug mode then my breakpoint is stuck in delete method. I am using
PostgreSQL 9.6.24 on x86_64-pc-linux-gnu, compiled by Debian clang version 12.0.1, 64-bit
version, and for pool connection Hikari-CP-3.2.0.
And If I let my debug running after long time (~45min) I am getting below error.
marked as broken because of SQLSTATE(08006), ErrorCode(0)\norg.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.
Thanks in advance.
There are two possible reasons for this.
Either your delete statement actually takes a really long time, or it is stuck on a lock.
45 min, is certainly a lot for simple delete and could only be expected when you are working on huge amounts of data, like many millions of rows. Use the explain plan to validate that the expected indexes are used.
I consider locks the more likely reason for the problem. You'll need to check what locks are present and where they are coming from. This wiki page about lock monitoring in PostgreSQL seems to be a good starting point.

Embeddable/ ManyToOne/ OneToMany not working

I' m quite knew to Java and currently I am working on a ChatProgramm.
So I want to create a table Messages embedded with the ID (USERNUMBER) of my table Contacts using Injections.
Here' s the class of my Message:
#Embeddable
#Entity(name = "MESSAGE")
public class Message implements Serializable {
#ManyToOne
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "INCOME_MESSANGE", nullable = false)
private String incomingMessage;
#EmbeddedId
#JoinColumn(name = "USERNUMBER", nullable = false)
private Contact contact;
ChatApplicationRemote chatApplicationRemote;
public Message(String ip, String msg) throws IOException {
incomingMessage = msg;
contact = chatApplicationRemote.getcontactByIP(ip.toString());
}
public Message(){
}
public String getIncomingMessage() {
return incomingMessage;
}
public Contact getContact() {
return contact;
}
And here my contacts:
#Entity(name = "CONTACTS")
#Embeddable
public class Contact implements Serializable {
/**
*
*/
private static final long serialVersionUID = -6855140755056337926L;
#Column(name = "NAME", nullable = false)
private String name;
#Column(name = "PRENAME", nullable = false)
private String vorname;
#Column(name = "IP", nullable = false)
private String ip;
#Column(name = "PORT", nullable = false)
private Integer port;
#Id
#OneToMany(mappedBy = "Message.incomingMessage")
#Column(name = "USERNUMBER", nullable = false)
private String usernumber;
public Contact(String usernumber, String name, String vorname, String ip, String port) {
super();
this.usernumber = usernumber;
this.name = name;
this.vorname = vorname;
this.ip = ip;
this.port = Integer.parseInt(port);
}
public Contact(){
}
public String getUsernumber() {
return usernumber;
}
//......
So in my Message, I get two errors:
#ManyToOne throws : Target entity "java.lang.String" is not an Entity
#EmbeddedID throws : de.nts.data.Contact is not mapped as an embeddable
So I googled for a while.. and found something abouta orm.xml which I hadn't have. And even if I create one, #EmbeddedID throws:Embedded ID class should include method definitions for equals() and hashcode() and the orm.xml Attribute "usernumber" has invalid mapping type in this context.
Can anyone please help?
Try
#Entity
public class Message implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#Column(name = "INCOME_MESSANGE", nullable = false)
private String incomingMessage;
#ManyToOne
#JoinColumn(name = "USERNUMBER", nullable = false)
private Contact contact;
#Transient
ChatApplicationRemote chatApplicationRemote;
..
}
#Entity
public class Contact implements Serializable {
private static final long serialVersionUID = -6855140755056337926L;
#Column(name = "NAME", nullable = false)
private String name;
#Column(name = "PRENAME", nullable = false)
private String vorname;
#Column(name = "IP", nullable = false)
private String ip;
#Column(name = "PORT", nullable = false)
private Integer port;
#Id
#Column(name = "USERNUMBER", nullable = false)
private String usernumber;
#OneToMany(mappedBy = "incomingMessage")
private LIst<Message> messages;
..
}
maybe as a starting point, but as JB Nizet suggested, start with some simple JPA/Java demos to get the basics first and build up. Your example has many more errors then just what the exception was showing, none of which are solved by just throwing in an ORM.xml.

Some parent entity value cannot be saved to child entity

When i save the job entity i was expecting that the child under job should also reflect in the db. The problem is that the ref_id and revision does not contain any value from the db.
here is the result from mysql db (removed confidential data)
This is my Job entity class
#Entity
#Table(name = "job")
public class Job implements Serializable {
private static final long serialVersionUID = -2075866246194059832L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private long id;
#Column(name = "ref_id")
private String refId;
#Column(name = "revision")
private int revision;
#Column(name = "appname")
private String appName;
#Column(name = "vendor")
private String vendor;
#Column(name = "version")
private String version;
#Column(name = "locale")
private String locale;
#Column(name = "platform")
private String platform;
#Column(name = "tier")
private String tier;
#Column(name = "category")
private String category;
#Column(name = "functional_tag")
private String functional;
#Column(name = "job_start_date")
private Date jobStartDate;
#Column(name = "author")
private String author;
#Enumerated(EnumType.STRING)
private Status status;
#Column(name = "release_version")
private String releaseVersion;
#OneToMany(mappedBy = "job", cascade = CascadeType.PERSIST)
private List<Task> tasks;
}
And here is the child
#Entity
#Table(name = "task")
public class Task implements Serializable {
private static final long serialVersionUID = -7395753611385528546L;
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "module_name")
private String moduleName;
#Column(name = "start_time")
private Date startTime;
#Column(name = "end_time")
private Date endTime;
#Enumerated(EnumType.STRING)
private Status status;
#Column(name = "machine_ip")
private String machineIp;
#Column(name = "data_center")
private String dataCenter;
#Column(name = "description")
private String description;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
#JoinColumns({#JoinColumn(name = "ref_id", referencedColumnName = "ref_id"),
#JoinColumn(name = "revision", referencedColumnName = "revision")})
private Job job;
}
Here is the code that persist the entity
#Service
public class QReaderService {
#Autowired
private JobRepository jobRepository;
#Autowired
private TaskRepository taskRepository;
public boolean addJob(Job job) {
Job previousJob = jobRepository.findByJobRefId(job.getRefId());
if (previousJob == null) {
**jobRepository.save(job);**
return true;
} else {
switch (job.getStatus()) {
case FAILED:
case EXCEPTION:
int revision = 0;
revision += previousJob.getRevision();
previousJob.setStatus(Status.FAILED);
jobRepository.save(previousJob);
break;
}
}
return true;
}
}
This is how i build the job entity
Job job = new Job();
job.setRefId("f78d9as7f98dsa7f97a97f98sda9f7");
job.setAppName("appname");
job.setLocale("locale");
job.setPlatform("platform");
job.setCategory("category");
job.setReleaseVersion("1.1");
job.setStatus(Status.PROCESSING);
job.setAuthor("author");
job.setFunctional("functional");
job.setJobStartDate(new Date());
job.setVersion("1.1");
job.setTier("tier1");
job.setVendor("vendor");
Task task = new Task();
task.setDescription("description");
task.setDataCenter("dataCenter");
task.setStartTime(new Date());
task.setStatus(Status.PROCESSING);
task.setMachineIp("ip");
task.setModuleName("module");
job.setTasks(new ArrayList<Task>(Arrays.asList(task)));
jobRepository.save(job);
To persist child entities when you call save on parent entity, both sides of the relations should be set.
job.setTasks(job.setTasks(new ArrayList<Task>(Arrays.asList(task)));
//Missing line //Important for persistence of child
task.setJob(job);
Hope this helps.

Categories