Instagram clone coding troubleshooting
Creating a post
Problem 1 : SQLIntegrityConstraintViolationException: Column ‘user_id’ cannot be null
When I ran the application after finishing the basic @PostMapping method, it kept on giving me the following error saying the user_Id was null.
2022-08-24 16:36:33.715 WARN 16508 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1048, SQLState: 23000
2022-08-24 16:36:33.715 ERROR 16508 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper : Column 'user_id' cannot be null
2022-08-24 16:36:33.727 ERROR 16508 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
java.sql.SQLIntegrityConstraintViolationException: Column 'user_id' cannot be null
🌧Cause
I checked the problem using the debugger. It turned out that the annotation @AuthenticationPrincipal I used to get the user details of the logged in user couldn’t fetch the correct information.

🌈Solution
Googled the issue, but couldn’t find the exact reason why this happens. So I decided to take away the annotation and call the user details directly from the tokenProvider.

Problem 2 : AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn
After creating the Image entity, I used @ManytoOne and @OnetoMany annotation to the Image and the Post entity respectively. I tried running the app and it gave me the following error message.
Caused by: org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn:
🌧Cause
The problem was becaused I used the @OnetoMany(mappedby=”post”) and @JoinColumn together in the Post entity.

However, @JoinColumn should be used from the owning side, in this case, the Image entity. The mappedby attribute is used from the referencing side to define the relationship.
For read: Difference between joincoulum and mappedby
🌈Solution
Problem solved by removing @JoinColumn from the Post entity.

Problem 3 : foreign key stays null in the database
When I wrote the code, what I thought was that the Image entity would fetch the post_Id as a foreign key. However, when I checked the database of Image after uploading the file, the post_Id column of the Image entity turned out to be null.
🌧Cause
The order of the code was the problem here. I had uploaded the file to the S3 bucket as soon as the file came into the PostService. This created a row in Image database. But because the post wasn’t saved to the Post database yet, the post_Id wasn’t created yet, which means that there is no post_Id to be saved together to the Image entity when uploading the image.

🌈Solution
I changed the logic and saved the post first after uploading the image to the S3 bucket.Then I converted the **ListImage**. Before, I didn't create the **Image repository**, because the images were already saved in the database even though I didn't create one. But this time I created the repository to make sure that the imageURl is saved with the post_id in the **Image** database.
![saving the List
⚡Better way to solve?
There was something called a convenience method which is used to set the relationship between the two entities.
Getting a Post/all Posts
Problem 1 : LazyInitializationException: could not initialize proxy
After correcting the Dtos, I ran the application again and it threw me a different error, but it was related to the proxy problem as well.
2022-08-25 10:06:35.012 ERROR 11720 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: could not initialize proxy [com.clonecode.inssagram.domain.User#1] - no Session] with root cause
org.hibernate.LazyInitializationException: could not initialize proxy [com.clonecode.inssagram.domain.User#1] - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:176) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final]
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:322) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final]
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:45) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final]
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final]
🌧Cause
I set @OnetoMany relationship with fetchType.LAZY and the error occurred because the session was gone when proxy tried to bring the lazily fetched object. I googled the solution and one of the solution I found was to change the FetchType as EAGER, but it didn’t work. Also it said that using fetchType.EAGER is not a good way to solve the problem.

🌈Solution
I added the @Transactional annotation on top of the get method to keep the transaction going.

⚡Better way to solve?
There are different ways to solve the problem but using Join Fetch directive is the best way.
reference: Different solutions for LazyInitializationException
Problem 2 : HttpMessageNotWritableException: Could not write JSON: could not initialize proxy
앱 실행을 했을 때 dto를 참조하는 proxy 오류가 났다. There were several issue messages regarding the initialization of proxy when running the application and all of them were pointing to the ResponseDtos.
WARN 14236 --- [nio-8080-exec-9] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: could not initialize proxy [com.clonecode.inssagram.domain.User#1] - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy [com.clonecode.inssagram.domain.User#1] - no Session (through reference chain: com.clonecode.inssagram.dto.response.ResponseDto["data"]->java.util.ArrayList[0]->com.clonecode.inssagram.dto.response.PostAllResponseDto["user"]->com.clonecode.inssagram.domain.User$HibernateProxy$3WV4xhH2["createdAt"])]
🌧Cause
The reason that caused the error were the entities called directly to the ResponseDto. When the response is returned as an entity, there can be a Json parser error.

🌈Solution
Make another dto for the entities called directly into the “ResponseDto”. The below is the example of the newly created UserProfileDto.

You can see below that the UserProfileDto is used to replace the User entity that was called directly into the PostAllResponseDto.

Viewing photos in AWS S3 bucket
Problem 1 : XML Access Denied
When viewing the urls from the frontend server, the imageUrls didn’t show the photos, saying that the access is denied.

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>2M0MEN0GTBW1E993</RequestId>
<HostId>QTZrLa+/D+M7RpGdTxg1bqpQFhO9i7vmyG9n7dPv8z+dfZkHwuNqIfgb+Wl9EUCDSQaT8nNuO3E=</HostId>
</Error>
🌧Cause
The S3 bucket returns the above error for anonymous requests to objects that aren’t public.
🌈Solution
From the bucket, I change the Permissions settings.
I turned off the ‘Block public access’ settings and let the public access the files in my bucket.

Then I added the bucket policy that allows anonymous user to read the images in the bucket.

Leave a comment