Cannot invoke "org.hibernate.mapping.PersistentClass.getTable()" because "classMapping" is null - spring-boot

I have an entity "MasterSegment" with a composite key as the primary key. This key has a reference to another entity "BkrApplication". When I start the app without Liquibase, tables are generated perfectly and everything works fine.
public class MasterSegment extends Auditable {
#EmbeddedId
private MasterSegmentId id;
#OneToOne
#MapsId("appId")
private BkrApplication app;
// getters setters omitted
}
#Embeddable
public class MasterSegmentId implements Serializable {
#Column
private String name;
#Column(name = "app_id", nullable = false)
private Long appId;
// getters setters omitted
}
The problem is when I try to generate a Liquibase migration using mvn clean install liquibase:diff, I get the following error: Cannot invoke "org.hibernate.mapping.PersistentClass.getTable()" because "classMapping" is null.
Without any hint in the exception message, and after many hours of debugging, I noticed that #MapsId causes the issue. I try to remove it and I got mapping issues.
Any help would be much appreciated.
Thanks

Related

#LastModifiedDate doesn't work when only nested nested object is updated

I have a Unit entity and I'm using the #LastModifiedDate annotation to keep track of the updates. The problem is that in case I only update the items field the updateDate field isn't updated with the new date but if I update any other fields in the Unit entity the updateDate field is updated properly.
//other annotations
#EntityListeners(AuditingEntityListener.class)
public class Unit {
#Id
#GeneratedValue
private UUID id;
private String unitId;
private String unitName;
//other fields
#LastModifiedDate
private LocalDateTime updateDate;
#OneToMany(cascade = {CascadeType.ALL, CascadeType.REFRESH})
#OrderBy("slotNumber")
private List<Item> items;
}
Unit repository
public interface UnitRepo extends CrudRepository<Unit, String> {
Set<Unit> findAllByProfileUsername(String username);
}
And my update method in my Unit service
public Unit updateUnit(Unit unit) {
return repo.save(unit);
}
#LastModifiedDate will only update the modified date when the changes have been made in the entity parameters, not the relationship. When you only modify the Item, updateDate will not be updated. You may find the open issue(for mongo) related to the same.
In case you want to modify the updateDate, you may implement the entity listeners with the #PrePersist or #PreUpdate (see JPA Lifecycle). You may also have a look into AuditorAware
You can use the callback methods in your Unit Entity class.which allows to detect the changes before / after to the entity class. #PreUodate and #PostUpdate you can try.
References -
https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/listeners.html

JsonIgnore annotation is not working with Lombok

I am facing really weird issue with Lombok and Jackson. Following of piece of code on which I am working.
#Getter
#Setter
#NoArgsConstructor
#XmlRootElement
public class Order{
//#JsonIgnore
#Getter(onMethod = #__(#JsonIgnore))
private boolean userPresent;
}
So what I want , this dto supposed to serialized as Json then this userPresent attribute should not come as response attribute. I though #JsonIgnore will work for me. But I think it as some issue with Lombok as per https://stackoverflow.com/a/57119494/2111677 article.
Then I changed the approach to use OnMethod.
Now , on eclipse compiling perfectly fine but when I am trying to compile using mvn then it gives me following error.
Could someone help me fix when its not working with maven.
The #__ style is for javac7. For javac8+ you have to use this variant:
#Getter(onMethod_=#JsonIgnore)
However, it is sufficient to have the #JsonIgnore annotation on either the field, the getter, or the setter. If it is present on at least one of those, the whole "virtual property" is ignored completely during (de-)serialization. So if that is what you want, you don't need that onMethod_.
If you want it to be ignored only during serialization, but not on deserialization, you have to add a #JsonProperty on the setter:
#JsonIgnore
#Setter(onMethod_=#JsonProperty)
private boolean userPresent;
It does not work, a workaround is using #JsonIgnoreProperties at class level:
#JsonIgnoreProperties({"email"})
This worked for me.
#RequiredArgsConstructor
#Setter
#NoArgsConstructor
#Entity
public class ProductColor {
#Id
#GeneratedValue
#NonNull
#Getter
private Long id;
#NonNull
#Getter
private String color;
#ManyToMany(mappedBy="colors")
#Getter(onMethod_ = #JsonIgnore)
private Set<Product> products;
}

Spring Data Rest Does Not Update Default Value in DB

I have a Spring Boot application using Spring Data REST. I have a domain entity called User with a boolean field isTeacher. This field has been already setup by our DBA in the User table with type bit and a default value of 1:
#Data
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // This Id has been setup as auto generated in DB
#Column(name = "IS_TEACHER")
private boolean isTeacher;
}
And the User repository:
public interface UserRepository extends CrudRepository<User, Long>{
}
I was able to add a new user by giving the below request and POST to http://localhost:8080/users, a new user was created in the DB having isTeacher value 1:
{
"isTeacher" : true
}
However, when I tried to change IS_TEACHER by giving PATCH (or PUT) and this request:
{
"isTeacher" : false
}
The response showed that "isTeacher" is still true and the value didn't get changed in the table either. Can someone please let me know why this is happening?
The issue is due to #Data annotation of lombok is ignoring if you have a field that start with isXx it generates getters and setters to boolean with isTeacher for getters and setTeacher for setters then you are not able to update correctly your property, if you put "teacher" when updating should work but you should solve this by overriding that setter.
#Setter(AccessLevel.NONE) private boolean isTeacher;
public void setIsTeacher(boolean isTeacher) {
this.isTeacher = isTeacher;
}

Relational database foreign keys in Spring Boot JPA/Hibernate

I'm using Spring Boot JPA with Gradle. I'm struggling to find a guide that I can follow which focusses on creating a relational database with the correct Syntax for Spring Boot. I had a go but I get this error
No property idTestCase found for type TestRun!
I want TestRun and TestData entities with a OneToOne relationship with each other, and a TestCase entity that has a OneToMany relationship with TestRun. I reckon that TestRun should contain the foreign keys for TestData and TestCase.
Many times I make changes and it will not build, and when it does build the tables do not look correct, this is what I created:
#Entity
public class TestRun {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
private long testRunId;
private Boolean result;
#OneToOne #JoinColumn(name="testData_id")
private TestData testData;
#ManyToOne #JoinColumn(name="testCase_id")
private TestCase testCase;
}
#Entity
public class TestCase {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
private long testCaseId;
private String name;
private String description;
#OneToMany(cascade=CascadeType.ALL, mappedBy="testCase",targetEntity=TestRun.class)
private Collection<TestRun> testRun;
}
#Entity
public class TestData {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
private long testDataId;
#OneToOne(cascade=CascadeType.ALL, mappedBy="testData",targetEntity=TestRun.class)
private TestRun testRun;
}
From the guides it isn't clear to me what goes in #JoinColumn(name= some say it needs to link to a field on your POJO and some say it doesn't. If I create the foreign key field in my POJO then I get two foreign key fields in the database table and if I don't it doesn't build at all.
For example from the error I can infer it wants me to add the following fields to TestRun:
private long idTestCase;
private long idTestData;
But then my database appears as:
SELECT * FROM TEST_RUN;
TEST_RUN_ID
ID_TEST_CASE
ID_TEST_DATA
RESULT
TEST_CASE_ID
TEST_DATA_ID
(no rows, 3 ms)
I tried setting #JoinColumn(name= to the name of the primary key field on the other side of the relationship but again it did not build.
Many thanks
I found the guide at JBoss to be the most helpful in describing the different mappings.

I need help for persisting into oracle database

There is a problem about generating id while persisting into database.
I added the following code to my jpa entity file, however I'm getting 0 for personid.
#Id
#Column(unique=true, nullable=false, precision=10, name="PERSONID")
#SequenceGenerator(name="appUsersSeq", sequenceName="SEQ_PERSON", allocationSize=1)
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "appUsersSeq")
private long personid;
EjbService:
#Stateless
public class EjbService implements EjbServiceRemote {
#PersistenceContext(name = "Project1245")
private EntityManager em;
#Override
public void addTperson(Tperson tp) {
em.persist(tp);
}
}
0 is default value for long type. The id will be set after invoking select query for the related sequence, which commonly is executed when you persist the entity. Are you persisting the entity? In case yes, post the database sequence definition to check it.

Resources