Currently my Project is using the JPA for the Database Connection.
I'm also using the default OdataJPA Processor.
How can i achieve not to include certain fields for example ("password") in my odata2 API response. Or do I really have to implement a customOdataJPAProcessor?
The easiest way for excluding some JPA entity attributes is to define a JPA-EDM mapping model. This is basically an XML file which adheres to this schema. You can read more about it in the documentation here: redefining OData JPA metadata.
You have two different ways of linking the mapping model XML, either you specify a file name of a file located in the WEB-INF folder (assuming that you are building a WAR) or, if this is not flexible enough, you can create a JPA EDM extension and return the mapping model file as a stream.
This is how such a file may look like:
<?xml version="1.0" encoding="UTF-8"?>
<JPAEDMMappingModel xmlns="http://www.apache.org/olingo/odata2/jpa/processor/api/model/mapping">
<PersistenceUnit name="My_Persistence_Unit">
<JPAEntityTypes>
<JPAEntityType name="MyEntity">
<EDMEntityType>MyEntity</EDMEntityType>
<EDMEntitySet>MyEntities</EDMEntitySet>
<JPAAttributes>
<JPAAttribute name="attribute" exclude="true" />
</JPAAttributes>
<JPARelationships />
</JPAEntityType>
</JPAEntityTypes>
<JPAEmbeddableTypes />
</PersistenceUnit>
</JPAEDMMappingModel>
Related
I have the following XML file:
<node name="FIXED_NAME">
...
</node>
Note that all elements in my XML are node (same name) and I can not change them for some reasons.
I am using java xml validator and xsd file for validation.
I want to validate that the name property for the root node must be FIXED_NAME.
How my xsd file should be?
I cannot think of any solution to your problem, for these reasons:
XSD 1.0 identifies the type of a tag by matching the hierarchy of tags in the XML document against the element/type definitions in the XSD. In your case, there is no hierarchy of names (because all tag names are the same).
XSD 1.1 provides some extra flexibility via xs:alternative and xs:assert - but they do not allow references to the parent axis.
For these reasons, I cannot think of any way to use the features of XML Schema to describe your XML.
I would like to know how I can get in POJOS generated by Hibernate tools when doing reverse engineering of a database the collections of relationships (OneToMany, ManyToMany) like List instead of Set.
Is there any way to specify in the file reveng.xml?
Answer depends on engineering pipeline. I use hibernate-tools 4.3.5.Final and Ant task hibernatetool with notable configurations:
<hbm2hbmxml/> for HBM files generation;
<hbm2java jdk5="true" ejb3="true"/> to create Java classes from HBM. Solution is in HBM contents.
Is there any way to specify in the file reveng.xml?
No. hbm2hbmxml is configured by reveng.xml. Péter's answer suggests to specify desired type in <column/>, but OneToMany has no column. Relationship may explicitly be defined as following
<table name="MY_TABLE">
<foreign-key constraint-name="FK_TO_MY_TABLE_IN_OTHER_TABLE">
<set property="otherTables"/>
</foreign-key>
</table>
Notice <set/> element. There is no <list/> or other collection in hibernate-reverse-engineering-3.0 namespace. I have not found a way to change collection type in reveng.xml or via Ant task parameters, so every relationship in generated HBM is <set> element (in hibernate-mapping-3.0 namespace).
Is there a way to change collection type?
Yes. HBM file must contain desired type element (<list>, <bag>, <map>, etc.) instead of <set>. By default Hibernate tools use templates in JAR folders hbm and pojo. Each of those may be overridden by files in subfolders of folder specified in templatepath attribute of hibernatetool Ant task. You need to provide custom FreeMaker templates in hbm folder with following modifications.
In the end of persistentclass.hbm.ftl replace
<#if c2h.getTag(property)!="version" && c2h.getTag(property)!="timestamp">
with (notice template name starts with list, desired collection type, and processed tag is set)
<#if c2h.getTag(property) == "set">
<#include "list.hbm.ftl"/>
<#elseif c2h.getTag(property)!="version" && c2h.getTag(property)!="timestamp">
In list.hbm.ftl remove following line (because set has no index property)
<#assign indexValue = value.getIndex()>
and replace mandatory element
<list-index>
<#foreach column in indexValue.columnIterator>
<#include "column.hbm.ftl">
</#foreach>
</list-index>
with (put whatever you like instead of ID, it is not present in generated Java code)
<list-index column="ID"/>
List implies order. I suggest to add OrderBy annotation with related entity ID field name. Add to list.hbm.ftl after <#include "meta.hbm.ftl">
<meta attribute="scope-get">#javax.persistence.OrderBy("id") public</meta>
maggu suggests to add extra-import meta attribute to have package name mentioned in class file only once, but in my experience it breaks build with undefined symbol.
Notice actual scope after annotation. There is no way to put it on separate line (whitespace gets trimmed).
Alternative to scope hack is adding specific annotation in pojo build stage (one with hbm2java) together with other annotations, e.g., add to Ejb3PropertyGetAnnotation.ftl within <#elseif c2h.isCollection(property)> block following line
<#if property.value.type.returnedClass.simpleName == "List">#javax.persistence.OrderBy("id")</#if>
<list> and <bag> lead to new ArrayList<>(0) as default field value, but list is exposed as useful java.util.List, while bag is only java.util.Collection. It should be possible to change this (also for set) via collection-type attribute, but it accepts only org.hibernate.usertype.UserCollectionType implementations, not JDK classes.
In my project I had to replace Set with List only for certain relationships, so my list.hbm.ftl contains <#if property.name == "otherTables">. You can adjust condition as needed.
i use Spring for DB operation. For now i save my sql query into a xml file, like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>This query returns something extremely useful.
</comment>
<entry key="date.sql">
"update something set time = ? where sharedkey = ?"
</entry>
</properties>
And in the JDBCTemplate i have this:
public Properties readProperties(String xmlFileName) throws Exception {
Properties properties = new Properties();
InputStream is = this.getClass().getClassLoader().getResourceAsStream(xmlFileName);
properties.loadFromXML(is);
return properties;
}
public void updateDate(){
properties = readProperties("queries.xml");
sqlQuery = properties.getProperty("date.sql");
jdbcTemplateObject.update(sqlQuery,new Object[] {time,token});
}
Work but i think is not the best solution, how i can that with Spring? or there is other library for that?
You can achieve this in multiple ways. the best way to follow is
1> By Placing the Queries in a Property File and call them using Spring PropertyPlaceHolder
2> You can Still Use XML and can Get the Query by using JAXB or SAX XML Parser.
See the ElSql library which provides this functionality.
The small ElSql project allows an external file of SQL statements to be easily loaded and managed. It was originally written to work with Spring, and still does (although it now works without Spring as a dependency).
The file may be stored in "raw" SQL, or using a DSL:
-- an example comment
#NAME(SelectBlogs)
#PAGING(:paging_offset,:paging_fetch)
SELECT #INCLUDE(CommonFields)
FROM blogs
WHERE id = :id
#AND(:date)
date > :date
#AND(:active)
active = :active
ORDER BY title, author
#NAME(CommonFields)
title, author, content
// Java code:
bundle.getSql("SelectBlogs", searchArgs);
The DSL breaks the file into #NAME blocks that can be referred to from code. Each block is defined by significant whitespace indentation.
Additional tags can be used, such as #PAGING (that inserts the necessary code for paging such as FETCH/OFFSET) and #AND (that only outputs if the specified variable exists, for dynamically building searches). The goal of the optional DSL tags is to provide the common basics that often hit when trying to build dynamic SQL in a database-neutral way.
We use it for our SQL and avoid the significant overhead of an ORM.
I am running a query to return State, City, and Zip from my database. How do I get JAX-RS (Jersey) to return this like this;
<State>
<City>
<Zip></Zip>
</City>
</State>
and so on......
Do I need to build an object that matches my xml structure, then pass that to JAX-RS, or can JAX-RS build it for me based on the resultset?
No, Jersey can't create the output directly from a ResultSet. That's because it has no idea how the data is supposed to be represented. You'll have to write a class to hold the results. You can use JAXB annotations on that class to provide greater control over how the XML looks.
You could use POJOs in your JAX-RS service. Then use JPA to map the objects to the database, and JAXB to map them to XML. For an example see:
Part 1 - The Database
Part 2 - Mapping the Database to JPA Entities
Part 3 - Mapping JPA entities to XML (using JAXB)
Part 4 - The RESTful Service
Part 5 - The Client
I'm using Xstream to serialize a EJB entity class to be transferred by a web service, but it also writes the database specific information in this case the following code. Is it possible to omit this information?
<oracle.toplink.essentials.internal.helper.DatabaseField>
<scale>0</scale>
<length>255</length>
<precision>0</precision>
<isUnique>false</isUnique>
<isNullable>true</isNullable>
<isUpdatable>true</isUpdatable>
<isInsertable>true</isInsertable>
<columnDefinition></columnDefinition>
<name>ZIPCODEID</name>
<table>
<name>ZIPCODE</name>
<tableQualifier></tableQualifier>
<qualifiedName>ZIPCODE</qualifiedName>
<uniqueConstraints/>
</table>
<sqlType>4</sqlType>
<index>0</index>
</oracle.toplink.essentials.internal.helper.DatabaseField>
From FAQ:
How do I specify that a field should not be serialized?
Make it transient, specify it with XStream.omitField() or annotate it with #XStreamOmitField
EclipseLink (open sourced from TopLink) JAXB has extensions specifically for mapping JPA entities to XML:
For more information see:
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA
If you use openJPA you can detach the object to get the naked entity.
Check ->
http://openjpa.apache.org/builds/1.0.0/apache-openjpa-1.0.0/docs/manual/ref_guide_remote.html
Hope it helps...