IntelliJ run spring boot JPA application says not-null property references a null or transient value , But working fine from terminal - spring

I have a microservice project using Spring Boot: 2.6.2, JPA, and H2 DB with JAVA 17.
when I run my project from IntelliJ as an application from configuration it shows the below exception while inserting data into DB:
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value
But when I run this project from the command line or STS it's working fine, There is no exception. And entry was inserted properly.
I am using H2 Db as a datasource at my application.yml for local run.
spring:
datasource:
url: jdbc:h2:mem:test;DB_CLOSE_ON_EXIT=TRUE;DB_CLOSE_DELAY=5
driverClassName: org.h2.Driver
username: admin
password: admin
In this application.yml flyway is also used but that is only for the dev env profile.
The entity that is showing issue for :
#Getter
#Setter
#ToString(callSuper = true)
#SuperBuilder(toBuilder = true)
#EqualsAndHashCode(callSuper = false)
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "EMPLOYEE")
public class Employee extends Basics {
#Id
#SequenceGenerator(
name = "ID",
sequenceName = "ID_SEQ")
#GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "ID")
#Column(name = "ID", updatable = false, nullable = false)
private Long id;
#Column(name = "USER_ID")
private Integer userID;
#Column(name = "HOST_DATE")
private LocalDate hostDate;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "Host_DATA_ID")
private POHostData poHostData;
#OneToOne(
mappedBy = "user",
cascade = {CascadeType.ALL})
#JsonManagedReference("Manager_Result")
private ManagerResult ManagerResult;
#OneToMany(mappedBy = "user", orphanRemoval = true, cascade = CascadeType.ALL)
#JsonManagedReference("Basicuser_Authorisation")
private List<Authorisation> authorisation;
#OneToOne(
mappedBy = "user",
cascade = {CascadeType.ALL})
#Valid
private HostLineUser hostLineUser; // for this hostLineUser its showing error
}
And the HostLineUser Entity is
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#SuperBuilder
#EqualsAndHashCode
#Entity
public class HostLineUser {
#Column(name = "COUNTRY_OF_HOST", length = 2, columnDefinition = "char")
private String countryOfHost;
#Column(name = "HOST_CODE")
private Integer hostCode;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "USER_ID", nullable = false)
#EqualsAndHashCode.Exclude
private Employee employee;
}

Related

JPA Hibernate Problem for One to One Relationship with Embedded ID

I am struggling with the following problem that I've been trying to solve. After checking solutions on StackOverflow and articles on Baeldung I still get different JPA errors when trying to map the following ONE-TO-ONE relationship between 2 Oracle SQL tables with composite PK in a SpringBoot application:
MASTER
ID
VERSION
1
2022.1
Constraint:
PK_MASTER PRIMARY KEY(ID, VERSION)
MASTER_DETAILS
MASTER_ID
VERSION
DETAILS
1
2022.1
details
Constraint:
PK_MASTER_DETAILS PRIMARY KEY(MASTER_ID, VERSION)
FK_MASTER_DETAILS FOREIGN KEY(MASTER_ID, VERSION) REFERENCES MASTER(ID, VERSION)
After some failures in trying to map it using the #OneToOne JPA annotation with both classes having #EmbeddedId set on the composite PK, I also installed JPA Buddy to check how it will be generated and that resulted in the following 4 classes:
Master.java
#Getter
#Setter
#Entity
#Table(name = "master")
public class Master {
#EmbeddedId
private MasterId id;
#OneToOne(mappedBy = "master")
private MasterDetails masterDetails;
}
MasterId.java
#Getter
#Setter
#Embeddable
public class MasterId implements Serializable {
private static final long serialVersionUID = 8254837075462858051L;
#Column(name = "id", nullable = false)
private BigDecimal id;
#Lob
#Column(name = "version", nullable = false)
private String version;
}
MasterDetails.java
#Getter
#Setter
#Entity
#Table(name = "master_details")
public class MasterDetails {
#EmbeddedId
private MasterDetailsId id;
#MapsId
#OneToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumns({
#JoinColumn(name = "master_id", referencedColumnName = "id", nullable = false),
#JoinColumn(name = "version", referencedColumnName = "version", nullable = false)
})
private Master master;
#Lob
#Column(name = "details", nullable = false)
private String details;
}
MasterDetailsId.java
#Getter
#Setter
#Embeddable
public class MasterDetailsId implements Serializable {
private static final long serialVersionUID = -8375336118866998644L;
#Column(name = "master_id", nullable = false)
private BigDecimal masterId;
#Lob
#Column(name = "version", nullable = false)
private String version;
}
When running the SpringBoot application with this JPA structure the run time error received is:
org.hibernate.PropertyNotFoundException: Could not locate field [id] on class [org.project.packages.MasterDetails]
After removing the #MapsId that cause this error the application starts but when trying to insert data in the tables I get the following error:
org.hibernate.id.IdentifierGenerationException: null id generated for:class org.project.packages.MasterDetails
Checking in the H2 test database I noticed that the FK on the Master_Details table was not present, but only the PK was set.
I would appreciate any help in pointing out how this problem can be solved: other annotations required (Cascade/FetchType) or in case there are any changes to be made to the database level (I also tried adding a separate identifier column in the Master_Details table defined as PK and only keep the FK to the Master table). Thanks in advance!
After many tries, I figured out to solve the issue.
I had to use a common key between the two entities and also FetchType.LAZY.
MasterDetails.class
public class MasterDetails {
#EmbeddedId
#AttributeOverrides({
#AttributeOverride(name="ID", column=#Column(name="MASTER_ID"))
})
private MasterId id;
#OneToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumns({
#JoinColumn(name = "master_id", referencedColumnName = "id", nullable = false),
#JoinColumn(name = "version", referencedColumnName = "version", nullable = false)
})
private Master master;
#Lob
#Column(name = "guidance", nullable = false)
private String guidance;
}
Master.class
public class MasterSheet {
#EmbeddedId
private MasterId id;
#OneToOne(mappedBy = "master", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private MasterDetails masterDetails;
}

JPA Repository.findByKeyEquals() returns not present value, but the value is exist on db

I'm developing an application that queries a database.
There are a few issues right now.
history.isPresent() == false when calling Optional<History> findByKeyEquals() intermittently. but value is exist on database
This is the information I got while tracking the issue.
All child entities are non-null.
In most cases, if the same function is re-executed, it is searched.
But sometimes it doesn't happen intermittently.
i think that i use incorrectly table relationship annotation (#OneToMany,#ManyToOne options..)
I want to solve this issue.
this is my code
History (Parent)
#Table(
indexes = {
#Index(columnList = "key", unique = true),
})
#Entity
#Getter
#ToString
#Audited
public class History implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(updatable = false, nullable = false, columnDefinition = "BIGINT UNSIGNED")
private Long id;
#Setter
#Column(nullable = false, columnDefinition = "CHAR(36)")
private String key = UUID.randomUUID().toString();
#Setter
#Temporal(TemporalType.TIMESTAMP)
#NotAudited
private Date started = new Date();
#Setter
#Temporal(TemporalType.TIMESTAMP)
#NotAudited
private Date finished;
#Setter
#OneToMany(
cascade = CascadeType.ALL,
fetch = FetchType.LAZY,
mappedBy = "history",
orphanRemoval = true)
#NotAudited
private List<Content> contents = new ArrayList<>();
...
}
Content (Child)
#Table
#Entity
#Getter
#Audited
public class Content implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(updatable = false, nullable = false, columnDefinition = "BIGINT UNSIGNED")
private Long id;
#Setter
#Column(columnDefinition = "LONGTEXT")
#NotAudited
private String content;
#Setter
#ManyToOne(targetEntity = History.class, fetch = FetchType.Lazy, optional = false)
#Audited
private History history;
...
}
Repository
public interface HistoryRepository
extends JpaRepository<History, Long>, RevisionRepository<History, Long, Integer> {
Optional<History> findByKeyEquals(final String key);
}

Spring context indexer causes issues with hibernate entity mapping

I have a project that is split between multiple modules, each module is imported into the main one as a maven dependency.
Persistence entities can be located at any of the projects but under the same package.
I have been trying to improve the startup time of the application by using the spring-context-indexer but it seems to cause an issue with detecting entities.
My #EntityScan is configured like this:
#EntityScan(basePackages = {"com.botscrew", "com.botscrew.demoadminpanel.entity.jpa","com.botscrew.admin.entity"})
The strange thing is that error looks like this
org.hibernate.AnnotationException: #OneToOne or #ManyToOne on com.botscrew.admin.entity.Bot.amioWhatsAppConfigs references an unknown entity: com.botscrew.admin.entity.services.configs.AmioWhatsAppConfigs
Essentially both entities are located under the same package but Bot entity was resolved but AmioWhatsAppConfigs was not.
The application starts perfectly fine without spring indexer.
I am using spring boot 2.2.1.RELEASE
Entities classes:
#Getter
#Setter
#Builder
#Entity
#ToString(of = {"id", "name"})
#AllArgsConstructor
#Table(name = "admin_bot")
#DiscriminatorValue("Bot")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Bot {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Convert(converter = EmojiConverter.class)
private String name;
private Integer timezone;
private String greetingText;
#Column(columnDefinition = "tinyint(1) default 1")
private Boolean active;
#Column(unique = true, updatable = false, nullable = false)
private String publicIdentifier;
#OneToOne(fetch = FetchType.LAZY)
private PersistentMenuEntity persistentMenuEntity;
//TODO FetchType.LAZY
#OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "widget_id")
private Widget widget;
//TODO FetchType.LAZY
#OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private MessengerConfigs messengerConfigs;
//TODO FetchType.LAZY
#OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private AmioWhatsAppConfigs amioWhatsAppConfigs;
#OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private TwilioConfigs twilioConfigs;
#OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private DialogflowConfigs dialogflowConfigs;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private ChatbaseConfig chatbaseConfig;
#OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private SupportSettings supportSettings;
#OneToMany
private Set<Tag> tags;
#OneToMany(mappedBy = "bot")
private List<Broadcast> broadcasts;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "admin_bot_features",
joinColumns = {#JoinColumn(name = "bot_id")},
inverseJoinColumns = {#JoinColumn(name = "feature_id")})
private Set<Feature> features;
public Bot() {
this.active = true;
}
public Bot(String name, DefaultWidgetProperties defaultWidgetProperties) {
this.publicIdentifier = UUID.randomUUID().toString();
this.chatbaseConfig = new ChatbaseConfig();
this.amioWhatsAppConfigs = new AmioWhatsAppConfigs();
this.timezone = 0;
this.name = name;
this.active = true;
this.messengerConfigs = new MessengerConfigs();
this.dialogflowConfigs = new DialogflowConfigs();
this.widget = new Widget(defaultWidgetProperties);
this.supportSettings = new SupportSettings(false);
}
}
#Getter
#Setter
#Entity
#Accessors(chain = true)
#ToString
#Table(name = "admin_amio_whatsapp_configs")
public class AmioWhatsAppConfigs implements AmioWhatsAppBot {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String channelId;
private String accessToken;
private String secret;
}
Please help
I am editing my answer please check example
#EntityScan(basePackages = {"com.botscrew",
"com.botscrew.demoadminpanel.entity.jpa","com.botscrew.admin.entity.services.configs.*"})

QueryDsl BooleanExpression - nested field is NULL

I want to create a predicate with QueryDSL and I don't know why but some nested field is NULL:
BooleanExpression emailSender = qFreight.message.account.user.id.eq(userId);
user is NULL.
qFreight.message.account.user gives me NPE error
And then in logs I have
.180 ERROR 7316 --- [nio-9090-exec-3] p.a.m.s.filter.JwtAuthorizationFilter : Request processing failed; nested exception is java.lang.NullPointerException
Of course I have generated QFreight, QMessage, QAccount, QUser... Where can bet the problem? I don't have any idea
UPDATE
My entities (the question is how to set #QueryInit properly):
#Entity
#Table(name = "freight")
#Getter
#Setter
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class Freight {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(nullable = false, updatable = false)
private Long id;
#QueryInit("*")
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "message_id")
private Message message;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "user_id")
private User user;
}
#Entity
#Table(name="message")
#Getter
#Setter
public class Message {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(nullable = false, updatable = false)
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "email_account_id", foreignKey = #ForeignKey(name = "FK_account_to_message"))
private Account account;
}
#Entity
#Table(name="account")
#Getter
#Setter
#NoArgsConstructor
#SuperBuilder(builderMethodName = "of")
public class Account {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(nullable = false, updatable = false)
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
private User user;
}
qFreight.message.account.user.id is not a valid JPQL expression. You'd have to create the joins between the entities explicitly: JOIN qFreight.message message JOIN message.account account JOIN account.user user. In QueryDSL this would be: .join(qFreight.message, QMessage.message).join(QMessage.message.account, QAccount.account).join(QAccount.account.user, QUser.user).where(QUser.user.id.eq(...)).
Furthermore, the QueryDSL metamodel by default is only initialized one level deep. This is a performance decision. If you need the metamodel to be initialized deeper (even though usecases are rare, because JPQL lacks support for implicit joins), you have to use #QueryInits: http://www.querydsl.com/static/querydsl/4.4.0/reference/html_single/#d0e2265

Could not fetch the SequenceInformation from the database ERROR but still everything works

I've created user and userRole tables
user entity
#Entity
#Table(name = "USERS")
public class User {
#Id
#Column(name = "USERNAME", nullable = false, unique = true)
private String username;
#Column(name = "PASSWORD", nullable = false)
private String password;
#Column(name = "ENABLED", nullable = false)
private boolean enabled = true;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch = FetchType.EAGER)
private Set<UserRole> userRole = new HashSet<>();
userRole entity
#Entity
#Table(name = "USER_ROLES", uniqueConstraints = #UniqueConstraint(
columnNames = { "ROLE", "USERNAME" }))
public class UserRole {
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "user_role_id",
unique = true, nullable = false)
private Integer userRoleId;
#Column(name = "ROLE")
private String role;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "USERNAME")
private User user;
When i launch my app i get an Error and this stack trace:
ERROR JdbcEnvironmentImpl:420 - Could not fetch the SequenceInformation from the database
org.h2.jdbc.JdbcSQLException: Column "start_with" not found [42122-197]
But i don't have any 'start_with' columns. Before my UserRole entity was without userRoleId column and everything worked fine but then i added it to do 'role' column not unique and then this happened. But still everything works fine, i just disturbed by this error, what can be the couse of it?
I suggest checking your Hibernate dialect.
I had a similar error because of a start_value column that Hibernate was looking for in sequences of my PostgresQL database. This field name is a default value in Hibernate's SequenceInformationExtractorLegacyImpl class which has many subclasses, each depending on your precise database server and its version. Hibernate loads the right class according to the dialect you specify.
In my case, I was using the org.hibernate.dialect.PostgreSQLDialect dialect, a (deprecated) class meant to be used with a PostgesQL 8.2 version. I switched to org.hibernate.dialect.PostgreSQL9Dialect since my database was hosted on a PostgresQL 9 server. And the issue was gone.

Resources