I'm not able to get the total count of my query.
JPAQuery query = super.prepareJPAQuery(userAccountHasWorkgroup).where(
userAccountHasWorkgroup.workgroup.id.eq(workgroupId);
query.count();
userAccountHasWorkgrouphas an #Embeddable class as ID.
javax.ejb.EJBTransactionRolledbackException: org.hibernate.exception.DataException: Operand should contain 1 column(s)
I add more information:
#Entity
#Table(name = "UserAccount_has_Workgroup")
public class UserAccountHasWorkgroup implements java.io.Serializable {
private static final long serialVersionUID = 6537213525312531347L;
private UserAccountHasWorkgroupId id;
private UserAccount userAccountByUserAccountId;
private Privilege privilege;
private UserAccount userAccountByApprovedByUserAccountId;
private Workgroup workgroup;
private boolean approved;
private boolean lastActiveWorkgroup;
private boolean isWorkgroupReferent;
...
}
#Embeddable
public class UserAccountHasWorkgroupId implements java.io.Serializable {
private static final long serialVersionUID = 6368469866573301127L;
private long userAccountId;
private long workgroupId;
...
}
If i do:
List<UserAccountHasWorkgroup> result = query.list(userAccountHasWorkgroup);
it works, but when I try to count:
Long count = query.count();
I receive the DataException
Instead of:
query.count();
I do
query.uniqueResult(Wildcard.count.as("count"));
It seems to work properly.
Related
Now, I'm aware that an Inner class cannot be an Entity in Hibernate.
I'll first show my code, please refer to my question below:
#Entity
#Table(name = "bags")
public class Bags extends AbstractModel {
private String brand;
private String condition;
private String size;
private Extras extras;
#ManyToOne
private Customer customer;
private class Extras {
private boolean box;
private boolean authenticity_card;
private boolean shoulder_strap;
private boolean dustbag;
private boolean pouch;
private boolean padlock_and_key;
private boolean bagcharm;
private boolean nameTag;
private boolean mirror;
}
}
Getters and setters are ommited. My question is:
If I want to have a slightly more complex object such as Extras, in which I represent the absence or not of several accessories, would it be better to create an additional table associated with bags OR is there a way around this?
Please let me know if I was not clear or you require additional information.
#Embeddable annotation is used to declare a class will be embedded by other entities.
#Embeddable
public class Extras {
private boolean box;
private boolean authenticity_card;
private boolean shoulder_strap;
private boolean dustbag;
private boolean pouch;
private boolean padlock_and_key;
private boolean bagcharm;
private boolean nameTag;
private boolean mirror;
}
#Embedded is used to embed a type into another entity.
#Entity
#Table(name = "bags")
public class Bags extends AbstractModel {
private String brand;
private String condition;
private String size;
private Extras extras;
#ManyToOne
private Customer customer;
#Embedded
private Extras extras;
}
I wrote a function get data from Db, it take most of the data but still lack some of column even i did define it in the entity.
Here is the result when i debug
data is null
here is my entity
#Entity
#Table(name="BANK_FEE_AND_LIMIT")
#NamedQuery(name="BankFeeAndLimit.findAll", query="SELECT b FROM
BankFeeAndLimit b")
public class BankFeeAndLimit implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private long id;
#Column(name="BANK_ID")
private Long bankId;
#Column(name="CASH_IN_FEE")
private Double cashInFee;
#Column(name="CASH_IN_FEE_AT_COUNTER")
private Double cashInFeeAtCounter;
#Column(name="CASH_IN_FEE_FROM_IB")
private Double cashInFeeFromIb;
#Column(name="CASH_IN_FEE_WITHOUT_LINK")
private Double cashInFeeWithoutLink;
#Column(name="CASH_OUT_FEE")
private Double cashOutFee;
#Column(name="CASH_OUT_FEE_WITHOUT_LINK")
private Double cashOutFeeWithoutLink;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="CREATE_DATE")
private Date createDate;
#Column(name="FEE_TYPE")
private Long feeType;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="LAST_UPDATE")
private Date lastUpdate;
#Column(name="MAX_CASH_IN_PER_DAY")
private Long maxCashInPerDay;
#Column(name="MAX_CASH_IN_PER_TRANS")
private Long maxCashInPerTrans;
#Column(name="MAX_CASH_OUT_PER_DAY")
private Long maxCashOutPerDay;
#Column(name="MAX_CASH_OUT_PER_TRANS")
private Long maxCashOutPerTrans;
#Column(name="MAX_NUMBER_CASH_IN")
private Long maxNumberCashIn;
#Column(name="MAX_NUMBER_CASH_OUT")
private Long maxNumberCashOut;
#Column(name="MIN_CASH_IN_FEE_AT_COUNTER")
private Long minCashInFeeAtCounter;
#Column(name="MIN_CASH_IN_FEE_FROM_IB")
private Long minCashInFeeFromIb;
#Column(name="MIN_CASH_IN_FEE_VALUE")
private Long minCashInFeeValue;
#Column(name="MIN_CASH_IN_FEE_WITHOUT_LINK")
private Long minCashInFeeWithoutLink;
#Column(name="MIN_CASH_IN_PER_TRANS")
private Long minCashInPerTrans;
#Column(name="MIN_CASH_OUT_FEE_VALUE")
private Long minCashOutFeeValue;
#Column(name="MIN_CASH_OUT_FEE_WITHOUT_LINK")
private Long minCashOutFeeWithoutLink;
#Column(name="MIN_CASH_OUT_PER_TRANS")
private Long minCashOutPerTrans;
#Column(name="STATUS")
private Long status;
#Column(name="WALLET_LEVEL")
private Long walletLevel;
#Column(name="WALLET_TYPE")
private Long walletType;
#Column(name="NUMBER_IBFT_FREE_BY_MONTH")
private Long numberIbftFreeByMonth;
#Column(name="NUMBER_CASH_OUT_FREE_BY_MONTH")
private Long numberCashOutFreeByMonth;
#Column(name="MAX_NUMBER_TRANSFER_IBFT")
private Long maxNumberTransferIbft;
#Column(name="MIN_IBFT_FEE_VALUE")
private Long minIbftFeeValue;
#Column(name="MIN_CASH_IN_FEE_FOR_PREPAID")
private Long minCashInFeeForPrepaid;
#Column(name="EXTRA_TRANSFER_IBFT_FEE")
private Long extraTransferIbftFee;
#Column(name="TRANSFER_IBFT_FEE")
private Long transferIbftFee;
#Column(name="CASH_IN_FEE_FOR_PREPAID")
private Long cashInFeeForPrepaid;
#Column(name="MIN_TRANSFER_IBFT_PER_TRANS")
private Long minTransferIbftPerTrans;
#Column(name="MAX_TRANSFER_IBFT_PER_TRANS")
private Long maxTransferIbftPerTrans;
#Column(name="MAX_CASH_IN_PREPAID_PER_TRANS")
private Long maxCashInPrepaidPerTrans;
#Column(name="MAX_TRANSFER_IBFT_PER_DAY")
private Long maxTransferIbftPerDay;
#Column(name="MAX_CASH_IN_PREPAID_PER_DAY")
private Long maxCashInPrepaidPerDay;
#Column(name="MAX_NUMBER_CASH_IN_PREPAID")
private Double test;
public Double getTest() {
return test;
}
public void setTest(Double test) {
this.test = test;
}
the null field is the test field which map to the MAX_NUMBER_CASH_IN_PREPAID column in the database.
Here is the data in database
data in database
other field is still can fetch normally, only this field can't be get.
i think you need to generate sitters and getters for the Columns you have then have a constructor to set the variables from within java classes or Controllers ( spring , servlet .. )
Map be there is scale problem. Try
#Column(name="MAX_NUMBER_CASH_IN_PREPAID", precision=0)
private Double test;
Reference : JPA mapping a Java Double to a SQL Number column
I'm having an issue performing a custom query through the use of a spring data jpa repository.
I have a repository class implementing JPARepository<>. Everything works as expected for all of the built-in CRUD queries along with some custom queries, but doing qualification among inner collections isn't working and is returning back a full result set as though the qualification of the collection did not exist.
For example, here is a query:
public interface MessageRepository extends JpaRepository<Message, Integer> {
#Query("SELECT a FROM Message a, Message_Topic b WHERE a.systemNm = :theSystem AND a. applicationNm = :theApplication AND b.topicNm = :theTopicName AND a.insertTs BETWEEN :theStartDate AND :theEndDate AND a.expirationDt > CURRENT_TIMESTAMP")
List<Message> findMessagesByTopic(#Param("theSystem") String theSystem,
#Param("theApplication") String theApplication,
#Param("theTopicName") String theTopicName,
#Param("theStartDate") Date theStartDate,
#Param("theEndDate") Date theEndDate);
With the following JPA entities:
Message:
#Entity
public class Message implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="message_id")
private int messageId;
#Column(name="application_nm")
private String applicationNm;
#Column(name="execution_instance_txt")
private String executionInstanceTxt;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="expiration_dt")
private Date expirationDt;
#Column(name="grouping_des")
private String groupingDes;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="insert_ts")
private Date insertTs;
#Column(name="message_detail_txt")
private String messageDetailTxt;
#Column(name="message_summary_txt")
private String messageSummaryTxt;
#Column(name="severity_des")
private String severityDes;
#Column(name="system_nm")
private String systemNm;
//uni-directional many-to-one association to Message_Topic
#OneToMany(fetch=FetchType.EAGER)
#JoinColumn(name="message_id", referencedColumnName="message_id")
private Set<Message_Topic> messageTopics;
Message_Topic:
#Entity
public class Message_Topic implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="message_topic_id")
private int messageTopicId;
#Column(name="message_id", insertable=false, updatable=false)
private int messageId;
#Column(name="topic_nm")
private String topicNm;
#Column(name="topic_value_txt")
private String topicValueTxt;
This is your query:
SELECT a FROM Message a, Message_Topic b WHERE a.systemNm = :theSystem AND a. applicationNm = :theApplication AND b.topicNm = :theTopicName AND a.insertTs BETWEEN :theStartDate AND :theEndDate AND a.expirationDt > CURRENT_TIMESTAMP
Where are Message and Message_Topic joined?, If you transform this query to a native query, is possible you can detect the fault.
I have a write converter as
public class CarConverter implements Converter<Car, DBObject> {
#Override
public final DBObject convert(final Car car) {
DBObject dbo = new BasicDBObject();
dbo.put("_id", car.getId());
// below line produces error
dbo.put("wheels", car.getWheels());
return dbo;
}
}
and my Car.java as
#Document(collection = "car")
public class Car implements Serializable {
private static final long serialVersionUID = 6121244806685144430L;
#Id private String id;
private List<Wheel> wheels;
// getters and setters
}
and my Wheel.java as (It is not document , just a bean)
public class Wheel implements Serializable {
private static final long serialVersionUID = 6121244806685144430L;
private String wheelId;
private String name;
//getters and setters
}
I got the below error when I try to save my Car object to mongodb.
SLF4J: Failed toString() invocation on an object of type [com.mongodb.BasicDBObject]
java.lang.RuntimeException: json can't serialize type : class com.mypackage.Wheel
at com.mongodb.util.ClassMapBasedObjectSerializer.serialize(ClassMapBasedObjectSerializer.java:77)
at com.mongodb.util.JSONSerializers$IterableSerializer.serialize(JSONSerializers.java:290)
at com.mongodb.util.ClassMapBasedObjectSerializer.serialize(ClassMapBasedObjectSerializer.java:79)
at com.mongodb.util.JSONSerializers$MapSerializer.serialize(JSONSerializers.java:317)
at com.mongodb.util.ClassMapBasedObjectSerializer.serialize(ClassMapBasedObjectSerializer.java:79)
at com.mongodb.util.JSON.serialize(JSON.java:55)
at com.mongodb.util.JSON.serialize(JSON.java:40)
at com.mongodb.BasicDBObject.toString(BasicDBObject.java:83)
at org.slf4j.helpers.MessageFormatter.safeObjectAppend(MessageFormatter.java:276)
at org.slf4j.helpers.MessageFormatter.deeplyAppendParameter(MessageFormatter.java:248)
at org.slf4j.helpers.MessageFormatter.arrayFormat(MessageFormatter.java:206)
at org.slf4j.helpers.MessageFormatter.format(MessageFormatter.java:148)
at org.slf4j.impl.Log4jLoggerAdapter.info(Log4jLoggerAdapter.java:341)
INFO : org.springframework.data.mongodb.core.mapping.event.LoggingEventListener - onBeforeSave:
com.mypackage.Car#1e4ec58, [FAILED toString()]
java.lang.IllegalArgumentException: can't serialize class com.mypackage.Wheel
at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:284)
at org.bson.BasicBSONEncoder.putIterable(BasicBSONEncoder.java:309)
at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:248)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:131)
at com.mongodb.DefaultDBEncoder.writeObject(DefaultDBEncoder.java:33)
at com.mongodb.OutMessage.putObject(OutMessage.java:289)
at com.mongodb.OutMessage.writeUpdate(OutMessage.java:180)
at com.mongodb.OutMessage.update(OutMessage.java:60)
at com.mongodb.DBCollectionImpl.update(DBCollectionImpl.java:275)
at com.mongodb.DBCollection.update(DBCollection.java:191)
at com.mongodb.DBCollection.save(DBCollection.java:975)
at com.mongodb.DBCollection.save(DBCollection.java:934)
Please somebody help me , what is the problem ? How can I fix it ?
I ran into this same error. My Document looked like this:
#Document
public class AnalyticsDailyData implements Serializable {
private static final long serialVersionUID = -5409790992784008124L;
#Id
#NotNull
#Valid
private AnalyticsMetaData metaData;
...
Adding an actual id field of type ObjectId made the error go away for me. I then set the metaData field to be indexed and unique.
#Document
public class AnalyticsDailyData implements Serializable {
private static final long serialVersionUID = -5409790992784008124L;
private ObjectId id;
#Indexed(unique = true)
#NotNull
#Valid
private AnalyticsMetaData metaData;
...
I am still able to query by metaData after adding a method to my Repo:
public interface AnalyticsDailyDataRepo extends PagingAndSortingRepository<AnalyticsDailyData, ObjectId> {
AnalyticsDailyData findOneByMetaData(AnalyticsMetaData meta);
}
I am trying out some very basic webservice. I get this exception everytime I try to return the Prtnr object.
Uncaught exception thrown in one of the service methods of the servlet: spitter. Exception thrown :
org.codehaus.jackson.map.JsonMappingException: Infinite recursion (StackOverflowError)
(through reference chain: org.hibernate.collection.PersistentSet[0]->org.abc.dvo.PrtnrGeoInfo["id"]->org.abc.dvo.PrtnrGeoInfoId["partner"]->
org.abc.dvo.Prtnr["prtnrGeoInfos"]->org.hibernate.collection.PersistentSet[0]->org.abc.dvo.PrtnrGeoInfo["id"]->org.abc.dvo.PrtnrGeoInfoId["partner"]->
org.abc.dvo.Prtnr["prtnrGeoInfos"]->org.hibernate.collection.PersistentSet[0]->org.abc.dvo.PrtnrGeoInfo["id"]->org.abc.dvo.PrtnrGeoInfoId["partner"]->
org.abc.dvo.Prtnr["prtnrGeoInfos"]->org.hibernate.collection.PersistentSet[0]->org.abc.dvo.PrtnrGeoInfo["id"]->org.abc.dvo.PrtnrGeoInfoId["partner"]->
...
at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:164)
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
...
The Prtnr class is :
public class Prtnr implements Cloneable, java.io.Serializable {
private static final long serialVersionUID = 201207021420600052L;
private Integer prtnrId;
private String creatUserId;
private Date creatTs;
private String updtUserId;
private Date updtTs;
private String prtnrNm;
private Integer cncilNum;
private Character prtnrTypCd;
private Set<PrtnrGeoInfo> prtnrGeoInfos = new HashSet<PrtnrGeoInfo>(0);
private Set<PrtnrDtl> prtnrDtls = new HashSet<PrtnrDtl>(0);
private Set<SuplyDtl> suplyDtls = new HashSet<SuplyDtl>(0);
private Set<TrnsprtDtl> trnsprtDtls = new HashSet<TrnsprtDtl>(0);
private Set<PrtnrFacil> prtnrFacils = new HashSet<PrtnrFacil>(0);
private Set<PrtnrHumanResrc> prtnrHumanResrcs = new HashSet<PrtnrHumanResrc>(0);
.....
.....
Getters and setters for these properties
...
}
The PrtnrGeoInfo class is :
public class PrtnrGeoInfo implements java.io.Serializable {
private PrtnrGeoInfoId id = new PrtnrGeoInfoId();
private String creatUserId;
private Date creatTs;
private String updtUserId;
private Date updtTs;
Getters and setters for these properties
}
The PrtnrGeoInfoId class is :
public class PrtnrGeoInfoId implements java.io.Serializable {
private Prtnr partner;
private GeoSegment geoSegment;
private static final long serialVersionUID = 201207060857580050L;
Getters and setters for these properties
}
I believe it is because of the classes refrencing each other. But how can this problem be resolved. Within the app which is Struts 2 and Spring, this object get passed just fine.
The controller class is as follows:
#Controller
#RequestMapping("/partners")
public class PartnerController {
#RequestMapping(value="/{id}", method=RequestMethod.GET, headers ={"Accept=text/xml,application/json"})
#ResponseBody
public Prtnr getPartner(#PathVariable("id") String id) throws Exception{
Prtnr partner = null;
try{
partner = partnerService.getPartnerById(Integer.valueOf(id));
System.out.println("******* Test message " );
}catch(Exception ex){
System.out.println("******* Exception thrown ... " + ex.getMessage());
}
return partner;
}
}
The calling class is
public class TestTemplate
{
private static final long serialVersionUID = 1130201273334264152L;
public static void main(String[] args){
Prtnr partner = (Prtnr)new RestTemplate().getForObject("http://localhost:9080/respondersApp/testWs/partners/{id}", Prtnr.class, "1");
System.out.println("partner name is : " + partner.getPrtnrNm());
}
}
In this link you can find how to solve this.
However below I'll paste the solution in practice.
It's very simple. Assuming that your database query already works without JSON, all you have to do is this:
Add the #JsonManagedReference In the forward part of the relationship (i.e. User.java class):
#Entity
public class User implements java.io.Serializable{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
#Column(name="name")
private String name;
#ManyToMany
#JoinTable(name="users_roles",joinColumns=#JoinColumn(name = "user_fk"),
inverseJoinColumns=#JoinColumn(name = "role_fk"))
#JsonManagedReference
private Set<Role> roles = new HashSet<Role>();
...
Add the #JsonBackReference In the back part of the relationship (i.e. Role.java class):
#Entity
public class Role implements java.io.Serializable {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#ManyToMany(mappedBy="roles")
#JsonBackReference
private Set<User> users = new HashSet<User>();
...
The work is done. If you take a look at your firebug logs, you'll notice that the infinite recursive loop has disappeared.
This is quite a common scenario for me when you are trying to convert entity classes into JSON format. The simplest solution is just to use #JsonIgnore on the reverse mapping to break the cycle.
You can annotate the second reference of Prtnr in PrtnrGeoInfoId with #JsonBackReference
The infinite recursion is due to the following:
Class Prtnr contains Set<PrtnrGeoInfo> prtnrGeoInfos and each PrtnrGeoInfo contains PrtnrGeoInfoId id which in turn contains Prtnr partner.
Thus, Prtnr -> PrtnrGeoInfo ->PrtnrGeoInfoId ->Prtnr, is causing a cyclic dependency which is a problem for Jackson when it is trying to do the POJO Mapping.
You need to remove this cyclic dependency to fix this exception.