how to get query result as XML in hibernate? - java

I am using struts2 with hibernate. Does anyone know if it is possible to return query result as XML instead of ArrayList of domain objects?

Hibernate by default maps and persists a database record thought POJO , but in fact it also supports persisting , mapping and representing a database record in XML by using an experimental features called Dynamic models.
For example , to output a record in XML:
/**Get the a new session that is in the DOM4J EntityMode**/
Session dom4jSession = session.getSession(EntityMode.DOM4J);
Element outputXML=(Element) dom4jSession.get(Employee.class, employeeId);
XMLWriter writer = new XMLWriter( System.out, OutputFormat.createPrettyPrint() );
writer.write( outputXML);
To configure the format of the outputted XML , you can only do it by mapping the entity in XML . AFAIK ,there are no annotation equivalent .

Hibernate is an Object-Relational Mapper, meaning it maps a Relational database to objects. You want to use Hibernate to return an object and then use an XML Serializer to convert to XML.
The Simple Serializer is probably the best one to get started with. The Website contains a lot of tutorials and examples.
http://simple.sourceforge.net/
However there are a ton of XML Serializers for Java:
http://karussell.wordpress.com/2009/09/03/xml-serializers-for-java/

Maybe you could, once you have the result use XStream to parse the entire result to XML. A simple tutorial on XStream is available here.

Related

How to convert a POJO to an BSON using MongoDB Java Driver

I've searched for a way to to convert a POJO into a BSON document. Unfortunately, the only answer you can find on the web is that MongoDB does this implicitly through the db.getCollection("some collection", Pojo.class) function. But there are some use cases where you want to convert a POJO into a BSON document.
One could be that you want to update a nested document in your MongoDB root document.
However, this isn't possible with the provided methods of the MongoDB Java Driver. The only way to do this is to write all the values manually in to a update expression.
db.getCollection("some collection", Pojo.class)
.updateOne(Filter.eq(id), Updates.set("myNestedDoc", new Document("some", "value"));
But it would be nice to do the same with a POJO. The advantages are obvious! Less duplicated code, better maintainable and less error prune.
But how can we accomplish this?
As described above, no answer can be found on the web. So I've searched the MongoDB Java Driver source code and found a way!
The BsonDocumentWrapper is a utility class to wrap a object as a BsonDocument. It uses the CodecRegistry which does the conversion internally.
db.getCollection("some collection", Pojo.class)
.updateOne(Filter.eq(id),
Updates.set("myNestedDoc",
BsonDocumentWrapper.asBsonDocument(lom, codecRegistry)));
)
You could also use the CodecRegistry object directly.
Pojo myPojo...
BsonDocument unwrapped = new BsonDocument();
BsonWriter writer = new BsonDocumentWriter(unwrapped);
Encoder<Pojo> encoder = codecRegistry.get(Pojo.class);
encoder.encode(writer, myPojo, EncoderContext.builder().build());
this.unwrapped = unwrapped;
But the utility class is more readable and maintainable.
This way you can safely use your existing POJOs to update your nested structures.
Keep in mind that you will replace the whole sub object, not only the fields that have been changed!
If you for some reason need to convert a BSON into a POJO you can use this sniped:
BsonDocument bson...
BsonReader reader = new BsonDocumentReader(bson);
Decoder<Pojo> encoder = codecRegistry.get(Pojo.class);
Pojo myPojo = encoder.decode(reader, DecoderContext.builder().build());
I hope this is useful to someone ;)

How to use Hibernate 5.2.10 MySQL JSON support without AttributeConverter or customUserType to map to Java Entity Class?

I am trying to map the MySQL JSON column to Java Entity class. Looking for the cleanest way of doing this.
Upon doing some research found 3 possible ways:
Extending AbstractSingleColumnStandardBasicType
Create a custom UserType
Use an attribute Converter
I used an attribute converter to convert the JSON column from String (as MySQL driver makes it to a String) to my required type - this works with both the Hibernate V4.3.10 and V5.2.10
I tried to find if JSON is natively supported in Hibernate and found the PR https://github.com/hibernate/hibernate-orm/pull/1395, based on the PR looks like it does add JSON mapping to the MySQL Dialect hence letting Hibernate know about the JSON Column.
Does this mean I can use something like this to map to JSON Column in DB ?#Column(name="json_type_column")
Private Object correspondingJsonAttribute;
If I cannot use it like this and need to use one of the above 3 methods, is there a reason I would need to upgrade to get the registerColumnType( Types.JAVA_OBJECT, "json" ); which is part of the PR and is present in Hibernate V5.2.10, Do I get any more features from V5.2.10 that support JSON columns?
I also looked into the corresponding test case to understand how the JSON column mapping is being done https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/access/MixedAccessTestTask.java, this uses #Access annotation via property, looks like it sets the corresponding JSON column variable in Entity to Map after converting it from String.
Any help is much appreciated.
Thanks!
Upon doing some research found 3 possible ways:
Extending AbstractSingleColumnStandardBasicType
Create a custom UserType
Use an attribute Converter
AttributeConvertor won't help you for this, but you can still use a custom UserType, or Hibernate Type Descriptors.
Does this mean I can use something like this to map to JSON Column in
DB?
#Column(name="json_type_column") Private Object
correspondingJsonAttribute;
No. The json type is just for JDBC so that Hibernate knows how to handle that JDBC object when setting a parameter on a PreparedStatement or when fetching a ResultSet.
Do I get any more features from V5.2.10 that support JSON columns?
No, but you just need to supply your own JSON type.
You can just use the hibernate-types which is available on Maven Central.
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>${hibernate-types.version}</version>
</dependency>
And use the provided JdonType from Hibernate Types as it works on MySQL, PostgreSQL, Oracle, SQL Server or H2 without doing any modifications.

How to automatically map POJOs to database to create tables using NetBeans

I have wrote some POJOs in NetBeans, and want to map these entities automatically to an empty database, to be tables.
I have read the netbeans official tutorial https://netbeans.org/kb/docs/java/hibernate-java-se.html#06a
But using Hibernate Mapping File as the document says can not choose the Database Table value, compare to the pic
(https://netbeans.org/images_www/articles/70/java/hibernate-j2se/mapping-wizard.png,
The actor value will not show since my database is empty.
So what should I do if I followed the tutorial, or is there any other method to automatically create tables by POJO in NetBeans?
There is one property hibernate.hbm2ddl.auto in hibernate which create tables as per your pojo structure.
Refer this doc.
MyBatis Generator can generate POJOs of tables. Visit this site to help you get started http://code.google.com/p/mybatis/wiki/Generator
Follow this tutorial on Hibernate mapping files.
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/xml.html
I never used NetBeans but if you write mapping file by yourself then you can use an empty database.
Use SchemaExport.export. Run following code in main() method:
AnnotationConfiguration configuration = new AnnotationConfiguration();
SchemaExport schemaExport = new SchemaExport(configuration);
schemaExport.export(true, true, true, false);

Reading a xml file in java

I am making a cloud like project. Right now, what I'm going to have is that I get the downloadable folder for the user to install. When users drag and drop files into the folder they are added to an XML file that looks like this:
<File>
<Name>application_for_employment2.doc</Name>
<Type>doc</Type>
<Size>144384</Size>
<Path>\application_for_employment2.doc</Path>
<Last_Mod>1365992658437</Last_Mod>
</File>
My questions:
What is the best way to read this and get the info?
Do I need to store this into my database?
Use JDOM for Parsing XML and JDBC connection to persist data.
Document document = (Document) builder.build(xmlFile);
Element rootNode = document.getRootElement();
List list = rootNode.getChildren("File");
For JDOM CODE Refer Exmaple link
XStream to get the XML into Beans and then Hibernate to put it into the database. Once your beans are set up and Hibernate is configured, the code is trivial:
Bean xml = (Bean)new XStream().fromXml(xmlStream);
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
xml.setId(session.save(xml));
session.commit();
You can use JAXB (JSR-222) to read the XML into Java objects (an implementation is included in Java SE 6).
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted
If you need to store the data to a database the. You could use the JPA APIs (JSR-327, with EclipseLink, Hibernate, OpenJPA, as the underlying implementation) to persist those same Java objects.
http://blog.bdoughan.com/2010/08/creating-restful-web-service-part-25.html
There are many ways of doing this. I would suggest using StAX for reading the XML and JDBC to store info in database.

After I got XML data, how to parse it and transfer to JSON?

In Jersey RESTful frame work, I know I can get xml data in client as following:
private static final String BaseURI = "http://DOMAN.com";
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource(BaseURI);
String xmlData = service.path("rest").path("todos").accept(
MediaType.APPLICATION_XML).get(String.class)
My question is how can I parse the xmlData then? I would like to get the needed data from xmlData, and transfer the needed data to JSON, what is the best way to implement this?
As a general rule, NEVER convert straight from XML to JSON (or vice versa) if you do not have to.
Rather, bind data from XML or JSON to POJOs, then do the other conversion. While it may seem non-intuitive this results in cleaner result and less problems, since conversions between POJOs and data formats have much more options, mature, well-designed libs; and POJOs are easier to configure (with annotations) and have more metadata to guide conversion process.
Direct conversions libs (like Jettison, see below) are plagued with various issues; often producing "franken-JSON", JSON that is technically correct but looks alien because of added constructs needed by conversion.
In case of Jersey, then, use JAXB for XML to/from POJOs, and Jackson for doing the same with JSON. These are libraries Jersey uses anyway; and direct usage is quite easy.
If you absolutely insist on direct conversion, you could try Jettison, but be prepared to hit a problem with Lists, arrays and Maps, if you need them (esp. single-element arrays -- arrays are problematic with XML, and auto-conversion often goes wrong).
If your service doesn't provide JSON as an option already (what happens if you change MediaType.APPLICATION_XML to MediaType.APPLICATION_JSON?), then I believe you have a few options, which I list in order of my preference.
Option 1: You have an XML schema for the the data
If you have an XML schema for the returned XML, you could use xjc to generate the JAXB annotated java classes and then leverage jackson to convert the instances to JSON data. I think this will get you going fast by leveraging this libraries over doing the parsing youself. Jackson is a robust library, used by glassfish for their Jersey(JAX-RS) implementation and I don't feel there is any risk in depending on this library.
Option 2: Use the json.org library, but I've had significant problem with this library having to do with its reflection-based methodology, etc. That said, it might work well for you...and you can test relatively easily and see if it does meet your requirements. If so...you're done! =)
Option 3: You don't have the XML schema and/or you want more control
as #Falcon pointed out, you can always use traditional XML parsing technologies to parse the XML into whatever you want. I'm partial to SAX parsing, but DOM could work depending on xml side
Regards,
Steve
Simplest and easiest way would be using org.json package : http://json.org/javadoc/org/json/XML.html
XML.toJSONObject(xmlData).toString()
Just this one line apart from necessary import statement will do it all.
Now that i have mentioned org.json library, lot of people may comment bad about it. Remember, I have said the simplest and easiest way, not the best or the most performant way ;-)
In case you are using maven, add this dependency :
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20090211</version>
</dependency>
Do you have any access to the "lower level interface" that generates the XML? If you do, the only change needed is to have the xml objects annotated with "#XmlRootElement". Then, you can just pass back the XMLobject as JSON without any further code.
Check Jsonix. If you have an XML schema, you can generate XML-JSON mappings and unmarshal/marshal XML in JavaScript. Very similar to JAXB (which Steve Siebert mentioned), but works on client.
// The PO variable provides Jsonix mappings for the purchase order test case
// Its definition will be shown in the next section
var PO = { };
// ... Declaration of Jsonix mappings for the purchase order schema ...
// First we construct a Jsonix context - a factory for unmarshaller (parser)
// and marshaller (serializer)
var context = new Jsonix.Context([ PO ]);
// Then we create an unmarshaller
var unmarshaller = context.createUnmarshaller();
// Unmarshal an object from the XML retrieved from the URL
unmarshaller.unmarshalURL('/org/hisrc/jsonix/samples/po/test/po-0.xml',
// This callback function will be provided with the result
// of the unmarshalling
function(result) {
// We just check that we get the values we expect
assertEquals('Alice Smith', result.value.shipTo.name);
assertEquals('Baby Monitor', result.value.item[1].productName);
});

Categories

Resources