The Java Programming Language
-
Need Guidance for Springboot and JPA
Hello Java Community.
Sorry if there's any grammar / spelling mistakes in this post. I'll try to convey my questions as clear as possible.
Introduction
I have basic knowledge about Java Programming. I took Programming Courses at my Uni and somewhat familiar with Java and OOP concepts in general ( barely ).
So for the last few weeks, I've been watching a great course from BouAli Free Code Camp Springboot Full Course on Youtube.
After completing the course, I challenge my self to create a basic E-Commerce Application with Springboot as the Framework, in order to practice my self with the knowledge i got from the course.
This Application will be a Simple Multi Tenant Application, where each tenant can create a product page, and a customer can purchase. Mind you i create this app to challenge my understanding about Springboot, and will not be a complex app for use.
Set Up
In the tutorial, there's a usage of
@ManyToMany
to map Many to Many Relationship. I thought that i could use Many To Many Mapping on Tenants <-> Users Relationship. In my understanding, AtenantEntity
could have multipleusers
assigned, and multipleusersEntity
could belong to atenantEntity
With that understanding, i try to create my
tenantEntity
anduserEntity
as follow ``` java tenantEntity // tenantEntity.java // Import Ommited for simplicity // Using Lombok Setter, Getter, AllArgs, NoArgs @Entity @Table(name = "T_TENANT") public class TenantEntity { @Id @GeneratedValue(strategy = GenerationType.UUID) private UUID id;@Column(nullable = false) private String tenantName;
@Column(length = 2000) private String tenantDescription;
private String website;
@Column(nullable = false) private Boolean isEnabled;
private Instant subscriptionExpiryDate;
@Column(length = 10) private int gracePeriodDays;
@ManyToMany(mappedBy = "tenants", fetch = FetchType.LAZY) private Set<UserEntity> users = new HashSet<>();
@Column(updatable = false, nullable = false) @CreationTimestamp private Instant createdAt;
@Column @UpdateTimestamp private Instant updatedAt; } ```
``` java userEntity // userEntity.java // Import Ommited for simplicity // Using Lombok Setter, Getter, AllArgs, NoArgs @Entity @Table(name = "T_USER") public class UserEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
@Column(nullable = false, unique = true) private String username;
@Column(nullable = false, unique = true) private String email;
@Column(nullable = false) private String firstName;
private String lastName;
@Column(nullable = false) private String password;
@Column(nullable = false) private boolean isEnabled;
@ManyToMany(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}) @JoinTable( name = "t_users_tenants_mapping", joinColumns = @JoinColumn( name = "fk_user_id", referencedColumnName = "id" ), inverseJoinColumns = @JoinColumn( name = "fk_tenant_id", referencedColumnName = "id" ) ) private Set<TenantEntity> tenants = new HashSet<>();
@Column(updatable = false, nullable = false) @CreationTimestamp private Instant createdAt;
@Column @UpdateTimestamp private Instant updatedAt; } ```
Generating this relationship in the database !
Creating New User
When creating new user, i could assign the Tenant to the User, resulting in these data
json // POST api/v1/users { "username": "newuser01", "first_name": "new", "last_name": "user", "email": "newuser@localhost", "password": "<P@ssw0rd/>", "is_enabled": true, "tenant_id": [ "79cf0ecf-976a-472c-b250-2192e630a4e4", "ac5b5786-c467-4dd6-b74d-7f70c83e1827" ] }
fk_user_id|fk_tenant_id | ----------+------------------------------------+ 6|79cf0ecf-976a-472c-b250-2192e630a4e4| 6|ac5b5786-c467-4dd6-b74d-7f70c83e1827|
Problem(s)
Now, how does one updates the data for the
ManyToMany
relationship? Say, i want to modify the membership of a user. i want to add new tenant or remove existing tenant?I try creating update method on my userRepository ``` // userRepository public interface UserEntityRepository extends JpaRepository<UserEntity, Long> {
@Transactional @Modifying @Query(""" update UserEntity u set u.username = :username, u.email = :email, u.firstName = :firstName, u.lastName = :lastName, u.isEnabled = :isEnabled, u.tenants = :tenants, u.updatedAt = :updatedAt where u.id = :id""") int updateUsernameAndEmailAndFirstNameAndLastNameAndIsEnabledAndTenantsAndUpdatedAtById( @Param("username") String username, @Param("email") String email, @Param("firstName") String firstName, @Param("lastName") String lastName, @Param("isEnabled") boolean isEnabled, @Param("tenants") Set<TenantEntity> tenants, @Param("updatedAt") Instant updatedAt, @Param("id") Long id ); }
which being called by userService
public UserResponseDTO updateUser(Long userId, UserRequestDto dto){ Instant updateAt = Instant.now().atZone(ZoneId.of("Continent/Ciy")).toInstant(); Set<TenantEntity> tenantEntitySet = getTenantEntitiesFromUserRequestDTO(dto);int updateRows = userEntityRepository.updateUsernameAndEmailAndFirstNameAndLastNameAndIsEnabledAndTenantsAndUpdatedAtById( dto.username(), dto.email(), dto.first_name(), dto.last_name(), dto.is_enabled(), tenantEntitySet, updateAt, userId );
UserResponseDTO userResponseDTO; UserEntity userEntity; if (updateRows == 1) { userEntity = userEntityRepository.findById(userId).orElse(new UserEntity()); } else { userEntity = new UserEntity(); } return userMapper.mapUserEntityToUserResponseDto(userEntity); } ```
resulting in a
NullPointerException
java.lang.NullPointerException: Cannot invoke "org.hibernate.sql.ast.tree.expression.Expression.getColumnReference()" because "pathSqlExpression" is null
in which resulted in a Hibernate Forum that states
Updating *-to-many collections is not possible, but please submit a bug report to our issue tracker([https://hibernate.atlassian.net 14](https://hibernate.atlassian.net)) to improve the error message.
Questions
So what is the best practice of doing things with ManytoMany associations? I've found many tutorials that state the use of @ManyToMany Annotations, but left after they're done inserting things to the database. How can i update the join table relations when the need to modify the data arises?
Is there a knowledge gap between me and Springboot especially with JPA? should i take another approach?
Any kind of feedback and suggestions are welcome
Thank You :D
Resources
- Free Code Camp | Springboot Full Course Youtube
- Baledung Explenation of ManyToMany
- vladmihalcea -> Just found out today, will read it later
- GeeksForGeeks ManyToMany
-
urChat v0.6.0 release - mostly backend stuff
github.com Release v0.6.0 · matty-r/urChatWhat's Changed Improved updateStyles performance Moved the Interface options panel to it's own InterfacePanel class. Rename Panels to URPanels. Move ProfilePanel and MainOptionsPanel from componen...
cross-posted from: https://programming.dev/post/9458575
> Hey all, > > Another update/release of urChat (Java IRC Client). This release had a lot of focus on general usability and backend cleaning up. Performance for updating the styles has been improved and i've also moved some of the major panels into their own classes to make it easier to add more options/panels at a future date. In doing this, there is less effort needed when adding more options as the this is all handled when using addToPanel() method: > > For Instance, i've added an option to toggle the tab icons, after creating the new
JCheckBox showTabIcons
, all that's needed to have it save to the preferences correctly is: > >java > URPanels.addToPanel(this, showTabIcons, null, Placement.DEFAULT, null, Constants.KEY_SHOW_TAB_ICON); >
> This adds it to the current JPanel (In this case the InterfacePanel), places it after the previous Component and then associates that with theKEY_SHOW_TAB_ICON
Preference key. Much easier than before. > > Support for HTTP proxies has also been added, so we've now got both SOCKS and HTTP proxies as an option. There is now better disconnection handling, it will automatically reconnect if it disconnects unexpectedly (after some time), and it will also rejoin all of the previously connected channels. > > I've also added in LOG4J2 for logging. At the moment there is a log4j2.xml config file included in the release JAR, but eventually i'll allow custom config files. I'm not 100% sure how I feel about it yet as it increased my release JAR file size from 247 KB to 2.47 MB which is quite a significant jump. > > Anyway, thanks everybody for your support and interest. Feel free to join the #urchat channel at irc.libera.chat to discuss improvements etc. :) Onwards and upwards to version 0.7.0! > > > GitHub Link - inside.java Deprecated Features in Java 18 thru 21 - Sip of Java – Inside.java
Many new features have been added to Java between 18 and 21, but some features are also on the way out. Let's review a few key features that have been deprecated or removed and alternatives for them!
The big one to remember with your older code - finalization is deprecated.
Closeable
orAutoCloseable
is preferred alongside atry-with-resources
block. -
urChat v0.5.1 release - Bug fixes, managing profiles, and custom nick formatting
github.com GitHub - matty-r/urChat: urChat is a Java based IRC Client designed around simplicity and minimal resource impact on your system.urChat is a Java based IRC Client designed around simplicity and minimal resource impact on your system. - GitHub - matty-r/urChat: urChat is a Java based IRC Client designed around simplicity and...
cross-posted from: https://programming.dev/post/8178703
> Version 0.5.1 of my IRC Client has been released. This time around it was mostly focussed around bug fixes largely to do with updating the styles. But I also added a couple of features. This was a shorter release from 0.4.0 as the changes weren't as significant. > > # Profile Handling > I wanted a way to easily manage profiles, especially during development. With this release i've added a Profiles page, which allows you to Create new profiles, clone an existing profile, rename, and delete profiles. You can also set a profile as the default to be used when loading the app. > > A majority of the effort went into keeping the Profile Picker (the combobox that changes the active profile) and the profiles page in sync which was done using listeners. New listeners were created for DELETE,CREATE, and CHANGE events as other components needed to add their own listeners to the queue to make sure they were also kept in sync, but also to update styles etc when the profile changes. > >
java > > public static void fireListeners (EventType eventType) > { > if(!listenerLists.containsKey(eventType)) > listenerLists.put(eventType, new EventListenerList()); > > Object[] listeners = listenerLists.get(eventType).getListenerList(); > > // Reverse order > for (int i = listeners.length - 2; i >= 0; i -= 2) > { > if (listeners[i] == ActionListener.class) > { > if (actionEvent == null) > { > actionEvent = new ActionEvent(listeners, i, null); > } > > ((ActionListener) listeners[i + 1]).actionPerformed(actionEvent); > } > } > } > >
> > All of this profile work was also used to centralise the loading and saving of profile information through the URProfileUtil helper class. This should hopefully help down the track. > > !Profiles Page > > # Custom Nick Format > This was similarly difficult to when I implemented the custom Date formatting. At least this time around I had an idea of how it might be implemented. However the difference was that I couldn't treat the resultant String as a whole, for example setting the Date format to [HHmm] i'd just return [0652] then insert that into the document, I had to contend with nick styles as well. > > In the end I settled with splitting whatever was placed into the Nick format field into three parts (Prefix, nick, Suffix). If you want something just on the right side of the nick, you put nick in the Nick format field, then whatever you want next to that. When placing the nick in the document, I set the attributes according to which part and then use this when updating the styles etc. > > !Custom Nick format > > -
I can't get TLS to work
I've been trying to follow the tutorial here, after failing to apply it to my project I tried to do the tutorial as it is, and I'm still getting handshaking failures.
On the server side, I have the following exception:
javax.net.ssl.SSLHandshakeException: No available authentication scheme
While on the client side, I have the following:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
I'd like to add that I'm starting fresh without any previous any keystore nor truststore, executing the commands in the tutorial does generate the key and trust stores.
I've tried making the CN the same as my machine hostname too, didn't work, nothing worked, the server and the client could never handshake.
Side note: this is just a demo I'm doing, so I don't really care if it has security flaws, I'm just trying to get TLS to work.
Thx in advance.
Update: I downgraded from JDK21 to JDK17 and it worked fine :/
-
Spring Security styles for enabling authentication
Hello there.
I'm writing a simple REST API using Spring Boot and I just added basic HTTP authentication in it. I'm currently using Spring Boot 3.1.5 and Spring Security 6.1.5.
There are different instructions on the web about how to correctly setup basic HTTP authentication for web requests, I believe they differ according to the Spring Security version.
It seems that latest guides use implementations of the UserDetails interface, which I found rather confusing, as it is not clear for me how exactly the framework uses that. Instead, I found much easier and clear to write my own class that inherits from AuthenticationProvider and override its
authenticate()
method to do all fancy things for me, including checking and setting user roles.I'd like to ask you if there is any drawback working with AuthenticationProvider that I cannot see right now, instead of newest documentation, that doesn't seem to just use default AuthenticationProvider.
Thanks!
-
Quality outreach heads-up - jdk 22: annotation processing behavior change – Inside.java
inside.java Quality outreach heads-up - jdk 22: annotation processing behavior change – Inside.javaThis Heads-Up is part of the regular communication sent to the projects involved, it covers an annotation processing behavior change in JDK 22.
-
P99 CONF 2023 | Reducing P99 Latencies with Generational ZGC by Stefan Johansson
YouTube Video
Click to view this content.
-
Persism: A zero ceremony ORM for Java
cross-posted from: https://lemmy.world/post/986041
> Persism is a light weight, auto-discovery, auto-configuration, and convention over configuration ORM (Object Relational Mapping) library for Java.
- blog.rasvi.io Benchmarking Java Virtual Thread Performance
Virtual thread is set to be released in JDK 21. This feature will bring significant benefits to many IO-bound frameworks. It will alleviate the burden on Java developers like me from having to write reactive-style code. The following tests have been conducted using JDK 21 EA build 25. CPU: Ryzen 480...
- vladmihalcea.com The best way to validate the DDL schema with Spring and Hibernate
Introduction In this article, we are going to see what is the best way to validate the DDL schema and the JPA entity mappings when using Spring and Hibernate. I decided to write this article after …