MongoDB Method threw 'org.springframework.data.mapping.MappingException' exception - mongodb

I have the following model
#Builder
#Data
#Document(collection = "overdue")
public class MGOverdue {
#Id
private String id;
private HashMap<Integer, HashMap<Integer, Overdue>> overdueList;
}
the repository.findById() throws the following exception
Method threw 'org.springframework.data.mapping.MappingException' exception
Caused by: org.springframework.data.mapping.MappingException: No property b found on entity class .<package>.receipt.Overdue to bind constructor parameter to!
Any suggestion please

I had to add #NoArgsConstructor to my model Overdue. It's similar to this one https://stackoverflow.com/a/53210768/7691891

Related

Spring Data MongoDB CompoundIndex Causes "Authentication Object Cannot Be Null"

Sorry if this is a duplicate question!
I am trying to make a compound index in the domain of one of my Spring Boot MongoDB apps. The app works fine, but when I add the #CompoundIndexes line to the top off the class, I receive an error on startup.
#Document(collection = "collection")
#CompoundIndexes({ #CompoundIndex(name = "compoundIndexA_B", def = "{'field_A' : 1, 'field_B': 1}") })
public class ControlPoint implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String id;
#NotNull
#Field("field_A")
private String fieldA;
#Field("field_B")
private String fieldB;
...etc
}
The error:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.core.MongoTemplate]: Factory method 'mongoTemplate' threw exception; nested exception is java.lang.IllegalArgumentException: Authentication object cannot be null
I am using Spring Boot v2.5.8. Any thoughts would be appreciated! I am not sure at all why a CompoundIndex begins affecting authentication... Deleting the annotation immediately makes the app work again.

Why JPQL ignore parent's fields?

App's stack: Hibernate, Spring Data, JPA.
There are some entities in the app. I try make JPQL-query in repository of my class OpenParagraph.
OpenParagraph:
#Entity
#Table(name = "open_paragraphs")
#NoArgsConstructor
#AllArgsConstructor
#Getter
#Setter
#ToString
public class OpenParagraph extends ProgramEntry {
#NotNull
#Column(name = "sort_num")
private Integer sortNum;
}
OpenParagraph has a parent: abstract class ProgramEntry.
ProgramEntry:
#MappedSuperclass
#NoArgsConstructor
#AllArgsConstructor
#Getter
#Setter
#ToString
public abstract class ProgramEntry extends AbstractBaseEntity {
#NotNull
#ManyToOne
#JoinColumn(name = "paragraph_id")
private Paragraph paragraph;
#NotNull
#ManyToOne
#JoinColumn(name = "program_id")
private Program program;
}
So, i tring to appeal to OpenParagraph's field "Paragraph", but IDEA tells me it's mistake:
It doesn't offer me the "program" field:
IDEA offer fields only from OpenParagraph, not from parent.
My question: this is IDEA's fail? If this is'nt IDEA's fail, then how i can call "program" in this query?
This is/was a bug of Intellij IDEA (maybe related to this?). But:
It is possible to query by fields of the super class (or MappedSuperclass). Here is an example:
#MappedSuperclass
#Getter
#Setter
public class Foo extends AbstractPersistable<Long> {
#Column
private String fooValue;
}
#Entity
#Getter
#Setter
public class Bar extends Foo {
#Column
private String barValue;
}
public interface BarRepository extends JpaRepository<Bar, Long> {
#Query("SELECT b FROM Bar b WHERE b.fooValue = ?1")
List<Bar> findByFooValue(String fooValue);
}
Given this, calling the repository method, something like this will be logged (with enabled sql logging):
Hibernate: select bar0_.id as id1_0_, bar0_.foo_value as foo_valu2_0_, bar0_.bar_value as bar_valu3_0_ from bar bar0_ where bar0_.foo_value=?
Hint:
If you are using Spring Boot (with the test dependency/dependencies and an embedded test db like h2), it is quite easy to execute such methods without to run the whole application. Here just a small snipped that would execute the method (even though this is no test, but that's enough to call methods somehow):
#SpringBootTest
public class BarRepositoryTest {
#Autowired
BarRepository barRepository;
#Test
public void testFindByFooValue() {
barRepository.findByFooValue("foo");
}
}

Hibernate map List<Enums> to Postgres enum

I need to map a list of Enums to a table in postgres.
For the generic mapping of a 1:1 relation I found this post very helpful. The code looks like:
#Entity(name = "Post")
#Table(name = "post")
#TypeDef(
name = "pgsql_enum",
typeClass = PostgreSQLEnumType.class
)
public static class Post {
#Id
private Long id;
private String title;
#Enumerated(EnumType.STRING)
#Column(columnDefinition = "post_status_info")
#Type( type = "pgsql_enum" )
private PostStatus status;
//Getters and setters omitted for brevity
}
But I have no troubles to figure out a solution if PostStatus is a List<PostStatus>. Because than the definition fails.
To make it specific: I have a table, e.g. PostRelations where I can store post_id and status. For the sake of sample I can store multiple status (e.g. timebased). So how to define it properly if I have
#Entity(name = "Post")
#Table(name = "post")
public static class Post {
#Id
private Long id;
private String title;
private List<PostStatus> status;
}
The approach to define it the same way cause an exception (which seems clear because the annotation is for a enum and not for a List)
Caused by: java.lang.ClassCastException: interface java.util.List
at java.lang.Class.asSubclass(Class.java:3404) ~[na:1.8.0_212]
at org.hibernate.type.EnumType.setParameterValues(EnumType.java:86) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
After some research and digging into the issue I finally solved the problem thanks to the sample for proper linking and setup:
#ElementCollection
#CollectionTable(name = "post_permission", joinColumns = #JoinColumn(name = "post_id"))
private List<PostStatus4Save> status;
and a thin wrapper around the existing enum PostStatus
#Embeddable
#Data //lombok
#TypeDef(name = "pgsql_enum", typeClass = PostgreSQLEnumType.class)
#AllArgsConstructor //lombok
#NoArgsConstructor //lombok
public class PostStatus4Save {
#Enumerated(EnumType.STRING)
#Type(type = "pgsql_enum")
PostStatus postPermission;
}

What's wrong with my JPQL query?

I am trying to implement join but I am facing error. I have product table and store table. product table references store table through foreign key as shown below:
Product.java
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long pId;
private String model;
private String brand;
private byte[] image;
private Long price;
private String currency;
private String transmissionType;
private String fuelType;
#ManyToOne
#JoinColumn(name="storeId")
private Store store;
// … getters and setters
}
Now, I show the Store.java
#Entity
public class Store {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long storeId;
private String locality;
private String city;
private String state;
private String zipCode;
private String phone;
// … getters and setters
}
Now , I show the repository
public interface ProductRepo extends JpaRepository<Product, Long> {
#Query("select p from Product p join p.storeId s where p.storeId = s.storeId and s.city = :city")
public List<Product> findByCity(#Param("city") String city);
#Query("select p from Product p join p.storeId s where p.storeId = s.storeId and s.state = :state")
public List<Product> findByState(#Param("state") String state);
}
Now, the error comes due to the last two queries where I implement join. What i want to do is get all products whose store is in particular city or state as you can see above.
The error I encounter is :
Error starting ApplicationContext. To display the auto-configuration
report re-run your application with 'debug' enabled. 2016-10-16
09:53:25.203 ERROR 16132 --- [ main]
o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'catalogueServiceController':
Unsatisfied dependency expressed through field 'productRepo'; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'productRepo': Invocation of init method
failed; nested exception is java.lang.IllegalArgumentException:
Validation failed for query for method public abstract java.util.List
com.practice.rest.assignment1.repository.ProductRepo.findByCity(java.lang.String)!
and so on ....
What is the error in my query ?
The query is invalid. You refer to a p.storeId which doesn't exist. I think something like this should be sufficient:
select p from Product where p.store.city = :city
Or:
select p from Product join p.store as store where store.city = :city
The upper should be sufficient as your JPA provider should be able to do the right thing for you then. The latter might be preferred if you want to be more specific about the join type to optimize the query.
The same applies to the other query. For future reference: everything you cut off the exception stack trace would've been the interesting part 😉. If persistence providers reject JPQL, they're usually very specific about the error they encounter. So you should be able to find something around p.storeId being an invalid reference somewhere deeper down the stack trace actually.

Using #OneToOne with Cascade.DELETE in embedded type

In an application I use EclipseLink 2.4.1 with Java Persistence 2.0.4.
I have a OneToOne mapping in an embedded class. Everything works fine, except deleting. When I try to delete the object containing the embedded class, the following exception occurs. I checked and I am not calling remove on the embedded object by myself somewhere in the code. Does anybody knows how to avoid this error or how to get around it?
Exception [EclipseLink-6002] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.QueryException
Exception Description: Aggregated objects cannot be written/deleted/queried independently from their owners.
Descriptor: [RelationalDescriptor(org.openlca.web.model.ProcessModelInfo --> [])]
Query: DeleteObjectQuery(org.openlca.web.model.ProcessModelInfo#77cc2975)
at org.eclipse.persistence.exceptions.QueryException.aggregateObjectCannotBeDeletedOrWritten(QueryException.java:240)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.prepare(ObjectLevelModifyQuery.java:205)
at org.eclipse.persistence.queries.DeleteObjectQuery.prepare(DeleteObjectQuery.java:327)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:614)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:575)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:820)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:751)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
at org.eclipse.persistence.queries.DeleteObjectQuery.executeInUnitOfWorkObjectLevelModifyQuery(DeleteObjectQuery.java:119)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2875)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1602)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1584)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1535)
at org.eclipse.persistence.queries.DeleteObjectQuery.executeDatabaseQuery(DeleteObjectQuery.java:194)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:852)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:751)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
at org.eclipse.persistence.queries.DeleteObjectQuery.executeInUnitOfWorkObjectLevelModifyQuery(DeleteObjectQuery.java:119)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2875)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1602)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1584)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1535)
at org.eclipse.persistence.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:334)
at org.eclipse.persistence.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:288)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1422)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:634)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1509)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:266)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1147)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:84)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
at org.project.ProcessDao.delete(ProcessDao.java:41)
The relevant class snippets look like this (Process and LongText are added in the persistence.xml) - The error occurs when trying to delete a process:
Entity Class Process
#Entity
public class Process {
#Id
#GeneratedValue(strategy = GenerationType.TABLE, generator = "process_seq")
#Column(name = "id")
private long id;
....
#Embedded
private ProcessModelInfo modelInfo = new ProcessModelInfo();
....
}
Embedded Class ProcessModelInfo
#Embeddable
public class ProcessModelInfo {
...
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name= "f_modelling_constants")
private LongText modellingConstants = new LongText();
...
}
Entity Class LongText
#Entity
#Table(name = "tbl_long_texts")
public class LongText {
#Id
#GeneratedValue(strategy = GenerationType.TABLE, generator = "long_text_seq")
#Column(name = "id")
private long id;
#Lob
#Column(name = "text")
private String text;
....
}
The ProcessDao.delete method looks like this:
#Override
public void delete(Process entity) throws Exception {
if (entity == null)
return;
EntityManager em = createManager();
try {
em.getTransaction().begin();
em.remove(em.merge(entity));
em.getTransaction().commit();
} finally {
em.close();
}
}
I can't see how this would occur, but if you can create a reproducible test case, please log a bug.
Check that you don't have any events that may be call remove on the embeddable.
Try debugging or set logging level to finest.
You may want to try the 2.5 release, as it may have been fixed (although I don't see any changes in the code).