I'm trying to fetch all the entries in my database, but only the reference fields. In my MongoRepository, I want to use a custom query, so it doesn't use the method name to build up the query. The following doesn't seem to work:
public interface JvRepository extends MongoRepository<Jv, String> {
#Query(value = "{}", fields = "{ id : 0, reference : 1 }")
public List<String> findAllJvReferences();
}
public class Jv {
#Id
private String id;
private String reference;
}
The error is:
Jv cannot be cast to java.lang.String
I tell it to not get the id, and do get the reference right? Why does it not return a String, but still a Jv?
I guess I should pass something in the value that tells Mongo to select everything, but I have no idea what. Or is there something else wrong with this code?
Related
I have a requirement of using a java model which will have couple of attributes but some of them will have values and some of them will not have and this is not fixed. For example if it has 4 attribute 3 may have values while passing it to the controller method or it may so happen 2 of them will have values but then rest of the attributes will be null. So to handle this i choose to use Query by example of spring , but i am getting
java.lang.IllegalArgumentException : "Should not reach the end of iterator"
I am trying to fetch data from a Azure CosmosDB. Below is the code i have used
ExampleMatcher macther = ExampleMatcher.matching().withIgnoreNullValues();
Example<RequestModel> exampleQ = Example.of(new RequestModel(
req.getEmp(), // these are the attributes which can have alternatively values or can be empty
req.getBase(),
req.getSeat(),
req.getRent()
),matcher);
sampleRepo.findByEmpOrBaseOrSeatOrRent(exampleQ ); // here i am getting the exception
The Repository
public interface SampleRepo extends CosmosRepository<TableA,String>,BaseContainerRepo{
}
The container
#Container(containerName= "${container-tableA}")
public class TableA extends BaseContainer{
}
Base model class
public class BaseContainer{
#Id
private String id;
private Inetger emp;
#PartitionKey
private String key;
private String base;
private String eqp;
}
The base container repo
public interface BaseContainerRepo{
List<BaseContainer> findByEmpOrBaseOrSeatOrRent(Example<RequestModel> exampleQ);
}
Can anyone please let me know where i am doing it wrong .
I've read the question Custom method for update query with spring data MongoRepository and my result would be the very same that it is in que previously mentioned question, the only difference would be that I want to do it by using a #Query annotated method. Is it possible? If so, how?
I have a entity and I what to update all documents with a value if a determined criteria has been match.
My entity:
#Document("accrual")
public class Accrual extends AbstractEntity {
#Serial
private static final long serialVersionUID = 1175443967269096002L;
#Indexed(unique = true)
private Long numericUserId;
#Indexed(unique = true)
private Long orderIdentifier;
private boolean error;
// sets, gets, equals, hashCode and toString methods
}
I would like to update the boolean error in every document found by searching for them using a list of Longs matching orderIdentifier attribute.
If it was in a relational database I would have a method like:
#Query(value = "update accrual set error = 0 where order_identifier in :list", nativeQuery = true)
updateErrorByOrderIdentifier(#Param("list") List<Long> orderIdentifiers)
You can try to use #Query annotation for filtering documents to be updated and #Update for providing actual update query.
#Query("{ 'orderIdentifier' : { '$in': ?0 } }")
#Update("{ '$set' : { 'error' : 'false' } }")
void updateAllByOrderIdentifier(List<Long> orderIdentifiers);
More details can be found here
I have an Enum class which has some values.
We've decided to remove one of these values and its all implementation from the code.
We dont want to delete any records from DB.
My Enum class is something like this:
public enum CourseType {
VIDEO("CourseType.VIDEO"),
PDF("CourseType.PDF"),
QUIZ("CourseType.QUIZ"),
SURVEY("CourseType.SURVEY"),
POWERPOINT("CourseType.POWERPOINT") //*this one will be removed*
...
}
My Course Entity:
#Entity
#Table(name = "CRS")
public class Course {
#Column(name = "COURSE_TYPE")
#Enumerated(EnumType.STRING)
private CourseType courseType;
#Column(name = "AUTHOR")
private String author;
....
#Override
public CourseType getCourseType() {
return courseType;
}
#Override
public void setCourseType(CourseType courseType) {
this.courseType = courseType;
}
....
}
After I removed the Powerpoint type from the Java Class and tried to fetch some values from the DB,
I get a mapping error for the removed type.
I have a code like this:
Course course = courseService.get(id);
If I gave a course id which its type is 'POWERPOINT' in the database,
the method gets the following error:
java.lang.IllegalArgumentException: Unknown name value [POWERPOINT]
for enum class [com.tst.enums.CourseType] at
org.hibernate.type.EnumType$NamedEnumValueMapper.fromName(EnumType.java:461)
at
org.hibernate.type.EnumType$NamedEnumValueMapper.getValue(EnumType.java:449)
at org.hibernate.type.EnumType.nullSafeGet(EnumType.java:107) at
org.hibernate.type.CustomType.nullSafeGet(CustomType.java:127) at
org.hibernate.type.AbstractType.hydrate(AbstractType.java:106) at
org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2912)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1673)
Is there any way when I try to retrieve a query result from DB,
hibernate will not fetch if that records' course_type column doesn't match with the any of the enum values in the code?
Do I have to use some kind of filter?
You can try use annotation #filter
#Filter(name = "myFilter", condition = "courseType <> 'CourseType.POWERPOINT'")
and enable it
session.enableFilter("myFilter")
If you can't use filters,
something like the following should work:
Add POWERPOINT back into the enum.
Add a deleted flag to the POWERPOINT enum value.
After the course list is loaded, remove courses that have a deleted courseType value.
New CourseType enum:
public enum CourseType
{
VIDEO("CourseType.VIDEO", false),
POWERPOINT("CourseType.POWERPOINT", true);
private boolean deletedFlag;
public CourseType(
existingParameter, // do whatever you are currently doing with this parameter
deletedFlagValue)
{
// code to handle existing parameter
deletedFlag = deletedFlagValue;
}
I have a document stored in MongoDB that looks something like this:
{ '_id' : 'XXX', 'myProps' : [ { '_id' : 'YYY', 'propA' : 'ValueA' }, { '_id' : 'ZZZ', 'propA' : 'ValueB' } ] }
I'm using Morphia to model this into Java objects. What I would like to do is query for elements within myProps that have a propA value of 'ValueA'. Is this possible? Is it possible to query for specific values within a subdocument? I've tried using queries like:
myProps.propA == 'ValueA'
...but, I still see all values of myProps being returned. Is there something I'm missing in my query? Or is it not possible to make such a query using Morphia/MongoDB?
UPDATE: My code thus far...
My entity and embedded classes:
#Entity
public class MyTestClass implements Serializable {
#Id
private ObjectId id;
#Embedded
private List<MyProps> myProps;
...
}
#Embedded
public class MyProps {
private String propA;
...
}
I have created the appropriate DAO class for it by extending BasicDAO. Here is my query:
Query<MyTestClass> q = this.myTestClassDAO.createQuery();
q.field("myProps.propA").qual("ValueA");
MyTestClass result = q.get();
The code executes correctly, but when I look at result.getMyProps() I see a list containing ALL of the myProps values, not just the ones with propA == 'ValueA'.
Using the fluent interface it should be something like field("myProps.propA").equal("ValueA").field("myProps.propA").notEqual("ValueB").
I'm trying to do a simple thing: call stored procedure which have a object type parameter.
This is what I have in db:
create or replace
TYPE TEST_TYPE AS OBJECT
(
test_field varchar(100)
)
and
CREATE OR REPLACE PROCEDURE TEST_PROC
(
PARAM1 IN TEST_TYPE
) AS
BEGIN
END TEST_PROC;
This is what I have in my java code:
#Embeddable
#Struct(name = "TEST_TYPE", fields = {"TEST_FIELD"})
public class TestStruct
{
private String testField;
public String getTestField() {
return testField;
}
public void setTestField(String testField) {
this.testField = testField;
}
}
and
#PostConstruct
public void init()
{
StoredProcedureCall call = new StoredProcedureCall();
call.setProcedureName("TEST_PROC");
call.addNamedArgument("PARAM1", "PARAM1", Types.STRUCT, "TEST_TYPE", TestStruct.class);
DataReadQuery dataReadQuery = new DataReadQuery(call);
dataReadQuery.addArgument("PARAM1");
TestStruct testStruct = new TestStruct();
List args = new ArrayList();
args.add(testStruct);
Object result = ((EntityManagerImpl)em.getDelegate()).getSession().executeQuery(dataReadQuery,args);
}
this is what I get in runtime:
Internal Exception: java.sql.SQLException: Invalid column type
Error Code: 17004
Call: BEGIN TEST_PROC(PARAM1=>?); END;
bind => [1 parameter bound]
Query: DataReadQuery()
I think I totally don't understand the subject of usage structs with JPA
please help me, good people :)
What is the shortest way to make this working?
Please send complete your code.
For call stored procedures using Spring, you have to extends StoredProcedure class. If you send your complete code, I can help better. sample pseudo code:
class CustomStoredProcedure extends org.springframework.jdbc.object.StoredProcedure
{
CustomStoredProcedure()
{
super([your-data-source], [package-name]);
declareParameter(new SqlParameter([your-struct-name]), Types.STRUCT));
compile();
}
Map<String, Object> execute([your-parameter])
{
return super.execute(inputs);
}
}
for better help, you have explain complete situation.
Your code looks correct.
Ensure that the descriptor was defined for the struct. (i.e. session.getDescrptor(TestStruct.class))
Can you call stored procedures with other types?
What database are you using, have you set your platform correctly to Oracle?
It seems that eclipselink skips descriptors for the #Struct and #Embeddable annotated classes unless they are referenced by some other class. The shortest way to make it working is to use workaround based on this assumption. Put additional class in the jar where your META-INF/persistence.xml is located:
#Entity
public class StructEntitiesWorkaround {
#Id
private String id;
private TestStruct testStruct;
}
You might want to use SimpleJdbcCall with Types.STRUCT.
Here is an example: https://docs.spring.io/spring-data/jdbc/old-docs/2.0.0.M1/reference/html/orcl.datatypes.html