Why is there no such feature as join fetch all lazy entities by default?
While designing an application I have faced some questions related to the lazy/eager fetching and all the stuff around.
Basically, as far I as understand, doing eager fetching is not a good thing and it is better to do a lazy load most of the time. Here we are running into an issue with lazy loading in the same transaction. We cannot reopen a new transaction to load the lazy entities.
One of the, I'd say, latest (or the most modern?) solutions is to use @NamedEntityGraph with @EntityGraph that are using JOIN FETCH to join the specified entities in one query.
So the question is - why is there no way to do a join fetch by default for all the lazy entities? I mean, now I have to add @NamedEntityGraph for every model where I have to lazy load the entities and add @EntityGraph to tell to use the NamedEntityGraph that I specified. If I add the entities to the model that means that at some point I am going to use them (despite the fact I mark them as lazy). What is the problem not to join fetch all the lazy entities by default? That would just simplify the code, I believe.
To my mind came a few answers:
- There is actually such a thing (but I haven't looked for it correctly)
- It is not good for performance even to join fetch all the entities (Though eager fetching is not good as well? But If I have the entities in my model it means that I will use them at some point so why not to join fetch all of them?)
- It is just no implemented at the moment.
To add more context - I use a few layers where some of them are repository and service. I want the repository and service to only work with models. But I have also got the DTO projections of the models and assemblers to map the models to DTO and back. I don't want to tie the DTO mapping to the service (which would actually solve the issue with lazy loading as we would use the same transaction, I believe). So I use assembler in controllers to map the models, that service returns, to the DTO and return those DTOs to the client.
See also questions close to this topic
-
recursion method not returning a string
I have to create a code that can find the longest palindrome contained inside sentences. (eg. Some people like cake but I prefer pie; the longest palindrome is i prefer pi). The problem is that upon running the code it doesn't return the palindrome. I'm not sure what the problem is but if anyone can figure it out I'd appreciate you letting me know. Thanks!
Code is below...
public class Recursion6 { static String recursion(String word, int currentLength, int x, String substring) { String reverse =new StringBuffer(word).reverse().toString(); if(word.length() == 1 ){ return substring; } if(word.charAt(0) != word.charAt(x)) { if(x == word.length() - 1) { recursion(word.substring(1), currentLength, 1, substring); } x++; recursion(word, currentLength, x, substring); } else { if(word.substring(0, x + 1).equalsIgnoreCase(reverse.substring(word.length() - (x+1), word.length()))) { if(word.substring(0, x).length() > currentLength) { currentLength = word.substring(0, x + 1).length(); substring = word.substring(0, x + 1); } recursion(word.substring(1), currentLength, 1, substring); } recursion(word.substring(1), currentLength, 1, substring); } return substring; } public static void main(String[] args){ Scanner sc=new Scanner(System.in); System.out.println("Enter a Sentence:"); String word=sc.nextLine(); System.out.println("The Palendrome is "+recursion(word.replaceAll(" ", ""), 1, 1, null)); sc.close(); } }
-
Groovy v3.0.7 doesn't support static interface methods
I have created a simple example groovy script under groovy v3.0.7, and Java 11.0.5
interface IFace { static String sMethod () { return "hello" } } class Test implements IFace { } IFace i = new Test() println i.sMethod()
however the parrot parser won't except this. If you run this you gives the following error
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: ideaGroovyConsole.groovy: 2: The method 'java.lang.String sMethod()' from interface 'IFace' must not be static. Only fields may be static in an interface. @ line 2, column 5. static String sMethod () { ^ 1 error
Why doesn't the latest 3.0.7 build support static interface methods. Have I missed something ?
-
HTTP Post method not supported by this URL when deployed to jboss EAP 7.1
I've a REST API, that is deployed on JBoss EAP 7.1. When I hit the URL at
http://localhost:8080/MyApp/group
in postman, it gives "HTTP method POST is not supported by this URL" error with status code 405.
When I deploy this API on embedded tomcat server, it works perfectly fine. Here is my controller
@RestController public class RequestController { @Autowired private GroupService groupService; @PostMapping( "/group" ) public GroupInfo fetchGroupInfo( @RequestBody GroupInfo groupInfo ) { long groupId = groupInfo.getGroupId(); return groupService.getGroup( groupId ); } }
main class
@SpringBootApplication public class MyApp extends SpringBootServletInitializer { /** * @param args */ public static void main(String[] args) { SpringApplication.run(MyApp.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder){ return builder.sources(MyApp.class); } }
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.my.package</groupId> <artifactId>MyApp</artifactId> <version>0.0.1-SNAPSHOT</version> <name>MyApp</name> <packaging>war</packaging> <properties> <java.version>1.8</java.version> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> </dependencies> <build> <finalName>MyApp</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
The deployment shows no error messages. However, it does show below warning
WARN [org.jboss.weld.deployer] (MSC service thread 1-4) WFLYWELD0013: Deployment optumRx-0.0.1-SNAPSHOT.war contains CDI annotations but no bean archive was found (no beans.xml or class with bean defining annotations was present).
And the class files are missing in the deployment folder in jboss. Can you please tell, what am I missing?
-
Spring boot Unable to evaluate the expression Method threw 'org.hibernate.LazyInitializationException' exception. using getter, ManyToMany relation
I've got two classes Participant and TimeWindow. Multiple participants can register for multiple TimeWindow, hence the ManyToMany relation
@Entity @Table public class Participant { @Id @SequenceGenerator( name = "participant_sequence", sequenceName = "particant_sequence", allocationSize = 1 ) @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "participant_sequence" ) private Long id; private String name; private String number; private String details; @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "ParticipantCreneaux") private Collection<TimeWindow> registeredTimeWindow; public Participant() { } public Participant(String nom, String num, String details) { this.name = nom; this.number = num; this.details = details; this.registeredTimeWindow = new ArrayList<>(); } public void addTimeWindow(TimeWindow c){ registeredTimeWindow.add(c); } public void removeTimeWindow(TimeWindow c){ registeredTimeWindow.remove(c); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public String getDetails() { return details; } public void setDetails(String details) { this.details = details; } public void setId(Long id) { this.id = id; } public Long getId() { return id; } public Collection<TimeWindow> getRegisteredTimeWindow() { return registeredTimeWindow; } }
And the TimeWindow class:
@Entity @Table public class TimeWindow { @Id @SequenceGenerator( name = "creneau_sequence", sequenceName = "creneau_sequence", allocationSize = 1 ) @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "creneau_sequence" ) private Long id; private LocalTime hourStart; private LocalTime hourEnd; public Collection<Participant> getListParticipants() { return listParticipants; } @ManyToMany(fetch = FetchType.LAZY,cascade=CascadeType.ALL,mappedBy = "registeredTimeWindow") private Collection<Participant> listParticipants; public TimeWindow(LocalTime hourStart, LocalTime hourEnd) { this.hourStart = hourStart; this.hourEnd = hourEnd; this.listParticipants = new ArrayList<>(); } public TimeWindow() { } public LocalTime getHourEnd() { return hourEnd; } public void setHourStart(LocalTime hourStart) { this.hourStart = hourStart; } public void setHourEnd(LocalTime hourEnd) { this.hourEnd = hourEnd; } public LocalTime getHourStart() { return hourStart; } public int getNbParticipants(){ return listParticipants.size(); } public void addParticipant(Participant participant){ this.listParticipants.add(participant); } public void removeParticipant(Participant participant){ this.listParticipants.remove(participant); } public void setId(Long id) { this.id = id; } public Long getId() { return id; } }
Right now I'm still learning Spring boot, I haven't found anything about it so far or anything that helped me.
The error is when I summon my participant's TimeWindow Collection that i've gotten through the DataBase in the Config class. In the debugger my Participant looks like this
id:123 name:"hisName" number:"321" details:"some details" registeredTimeWindow:{PersistentBag@10927}Unable to evaluate the expression Method threw 'org.hibernate.LazyInitializationException' exception.
At first i thought it was normal because of the Lazy option, i had to invoke the array through the getter, however it is wrong and the getter give me the exact same object.
FetchType.EAGER works fine, however I can't afford to do it. I've tried to get some help from someone a bit more experienced than I am, but without success. It should be possible to work around that issue within the JPA Repositories, but it feels like such a waste not to be able to use the getter.
-
Hibernate exhausted result set
I have a table which name is AsyncFcmNotification , this table has partitioned on a timestamp column. when I want to execute this query.
do { try (HibernateSession session = SessionManager.openSession()) { //noinspection unchecked List<AsyncFcmNotification> asyncFcmNotifications = session.createQuery("from AsyncFcmNotification where sent = false") .setFirstResult(offset) .setMaxResults(count) .list(); updateUnsendNotif(asyncFcmNotifications, session); offset += 100; } logger.info(offset + " notif has updated"); } while (offset < asyncFcmNotificationsCount);
asyncFcmNotificationsCount value is 105220;
I get these exceptions
-
Spring custom sorting in Sort.of
Is there any way to use
Sort.of
with this kind of sorting?@Query("SELECT l FROM Livestream l WHERE l.status IN ('LIVE', 'FUTURE') ORDER BY CASE WHEN l.status = 'LIVE' THEN -1 ELSE 0 END ASC") fun findLiveAndFuture(pageable: Pageable): Page<Livestream>
-
Where to Learn Java development(web development) without spring or springboot
I started to learn java web development. So I started with Springboot. I was able to understand Springboot but not in depth, for which I started to learn some concepts of spring which definitely helped. But now I want go deeper. So my question is,
a) Where should I learn raw Java web development as people used to do without Spring, Springboot, Hibernate and all the other tools, because without understanding this I wont ever get comfortable with Springboot or Spring. What books, video lectures or websites I should follow.
b) Should I even do this.(Keeping in mind I actually want go in depth)
-
Remote database connection with spring boot
I have connected remote database by following below properties:
spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://<server-ip>:3306/db_name spring.datasource.username= spring.datasource.password= spring.datasource.testWhileIdle=true spring.datasource.validationQuery=SELECT 1 spring.jpa.database=MYSQL spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect spring.jpa.hibernate.ddl-auto=validate spring.jpa.generate-ddl=true spring.jpa.show-sql=true
I didn't get any error of database while building application. All crud operations are successfully done without any error while testing the application in local. But data is not updating in remote database. I didn't catch the issue. Could you please help me to solve that issue.
Thanks in advance.
-
Mapping between two classes with JpaRepository SpringBoot
Well I have a class Service and a class Employee
Service.java
import lombok.Data; import javax.persistence.*; @Data @Table(name = "services") @Entity public class ServiceResource { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private String date; private String longitude; private String latitude; @ManyToOne @JoinColumn(name="employee_id") private EmployeeResource employee; }
Employee.java
import lombok.Data; import javax.persistence.*; @Data @Table(name = "employees") @Entity public class EmployeeResource { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private String longitude; private String latitude; }
Now I'd like to build my application that the mapping between service and employee is done with JPA. Is that even possible and how?
- Why dose the my service class's createPerson() return null?
-
Why application is failing to start for findAll method with Specifications?
I'm using spring-data-dynamodb in my boot app.
Repository class:
//.. imports class MyRepository extends PagingAndSortingRepository<User, String> { Page<User> findByName(String name, Pageable pageable); Page<User> findByJoinedDateBetween(String startDate, String endDate, Pageable pageable); @EnableScan @EnableScanCount Page<User> findAll(Pageable pageable); }
With above repository class, the application starts and returns expected output.
But, with below repository class setup (adding
JpaSpecificationExecutor<User>
)://.. imports class MyRepository extends PagingAndSortingRepository<User, String>, JpaSpecificationExecutor<User> { Page<User> findByName(String lastName, Pageable pageable); Page<User> findByJoinedDateBetween(String startDate, String endDate, Pageable pageable); @EnableScan @EnableScanCount Page<User> findAll(Specification<User> specs, Pageable pageable); }
the app is failing to start with:
org.springframework.data.mapping.PropertyReferenceException: No property findAll found for type User!
Am I not using it correctly? Is this because there is no support for
Specifications
at spring-data-dynamodb? Are@EnableDynamoDBRepositories
andJpaSpecificationExecutor<User>
compatible? -
Java Spring Data : Sort By ID Desc
I just want my Data to be sorted by ID Descendent and i don't know how to do and this is my code in service layer
public Page<Facture> selectByPage(Pageable p) { Page<Facture> pagedResult = factureRepository.findAll(p); return pagedResult; }