Mapstruct case insensitive mapping - java

is there a way in mapstruct to ignore the case of the fields when mapping. let say i want to map following two classes
public class Customer {
private String ID;
public String getID() {
return ID;
}
public void setID(String iD) {
this.ID = iD;
}
}
public class CustomerDetails {
private String id;
public String getId() {
return ID;
}
public void setId(String id) {
this.id = id;
}
}
MapStruct is not automatically mapping the fields because getter methods names that doesn't match. Is there a way to configure MapStruct to ignore the case of the fields and map them automatically

A custom AccessorNamingStrategy can be implemented that would lowercase the element name and thus making it case insensitive.
e.g.
public class CaseInsensitiveAccessorNamingStrategy extends DefaultAccessorNamingStrategy {
#Override
public String getPropertyName(ExecutableElement getterOrSetterMethod) {
return super.getPropertyName( getterOrSetterMethod ).toLowerCase( Locale.ROOT );
}
#Override
public String getElementName(ExecutableElement adderMethod) {
return super.getElementName( adderMethod ).toLowerCase( Locale.ROOT );
}
}

Not sure if you can configure mapstruct to map case insensitive but you always can define what should be mapped like this:
#Mapping(source = "ID", target = "id")
CustomerDetails toCustomerDetails(Customer customer);

Related

Hibernate Field Annotaion Behaviour

Please help me to understand why hibernate field based annotation works based on the primarykey field?.
Model Class 1 takes docnum field value from getter and Model Class 2 too.Inspite of both places only docnum is annotated based on the getter only.It works based on id field which is having annotaion in field of Model Class 2 and in Model Class 1 based on getter.
Model Class 1:
#Entity(name="RDT_ORDER")
public class Order {
private int id;
private String docnum;
#Id
#Column(name="ORDID")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name="ORD_DOCNUM")
public String getDocnum() {
return docnum+" getter";
}
public void setDocnum(String docnum) {
this.docnum = docnum;
}
}
Model Class 2:
#Entity(name="RDT_ORDER")
public class Order {
private int id;
private String docnum;
#Id
#Column(name="ORDID")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name="ORD_DOCNUM")
public String getDocnum() {
return docnum+" getter";
}
public void setDocnum(String docnum) {
this.docnum = docnum;
}
}
Output :table(RDT_ORDER) values
ID DOCNUM
5 docnum5
6 docnum6 getter

Boolean field Hibernate QueryException: could not resolve property

I am really newbie to Hibernate and it's been like two hours trying to figure it out how to fix this issue. I am using Hibernate 4 and Postgres 9.3
Given the CatalogBase class
#MappedSuperclass
public class CatalogBase {
#Id
#Type(type = "pg-uuid")
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
protected UUID id;
}
And the derived User class
#Entity
#Table(name="erpuser")
public class User extends CatalogBase {
private String lastName;
private String name;
private String email;
private boolean isSystemAdministrator;
#Type(type="org.hibernate.type.StringClobType")
#Column(nullable = false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="lastname")
#Type(type="org.hibernate.type.StringClobType")
#NotNull(message = "es campo mandatorio")
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Column(length = 100,unique = true)
#NotNull(message = "es campo mandatorio")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name = "issystemadministrator", nullable = false)
public boolean isSystemAdministrator() {
return isSystemAdministrator;
}
public void setSystemAdministrator(boolean isSystemAdministrator) {
this.isSystemAdministrator = isSystemAdministrator;
}
}
I am trying to filter just the first result of a query using Hibernate Criteria. Like this
public boolean existsSystemAdministrator() throws NoSuchAlgorithmException{
Criteria criteria=currentSession()
.createCriteria(User.class)
.add(Restrictions.eq("isSystemAdministrator", true));
return criteria.uniqueResult() != null;
}
But I always get org.hibernate.QueryException: could not resolve property: isSystemAdministrator exception
I have changed to all lowercase since the database field is like that, but it didn't work either. From what I've read Hibernate maps with the Java property, which hasn't been the case as well.
Have tried also change the isSystemAdministrator field to Boolean instead of boolean, but it didn't work out either.
I know this must sound stupid to any Hibernate guru, if someone can come up with an answer that would save me lots of time.
Thanks in advance.
You should adhere to the JavaBeans spec (http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html). The field should be 'systemAdministrator', and the method should be 'isSystemAdministrator'.
The problem is in #Id annotation in CatalogBase class. If you change so it will work fine:
#MappedSuperclass
public class CatalogBase {
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
#Id
#Type(type = "pg-uuid")
protected UUID id;
}
You can have 2 access types in Hibernate. Property access (as you did) or field access. Hibernate will guess the access type from the position of #Id or #EmbeddedId.
As I know (I am not a Hibernate guru), it should be no difference between these two access types. But some frameworks requires to have field access. Anyway, I do not know why your implementation does not work for querying and have not found any other explanation.

Spring Data Query Construction Using Method Name and Object Parameter

I was wondering if it was possible to not need the #Query annotation and let Spring Data construct the JPA Query based on my method name and method parameters for the below entity relationship. I want to retrieve a list of ItemLocations that are related to a particular Item. I tried the below signature and it didn't work without the #Query. Is it also more proper (efficient/effective) to pass in the Item.id instead of the Item object itself?
Spring Data Version: 1.3.4.RELEASE
Working Spring Data Repository API:
#Query("FROM ItemLocation where item = ?")
public List<ItemLocation> getAllItemLocations(Item item);
Desired Spring Data Repository API:
public List<ItemLocation> findAllItemLocations(Item item);
JPA Enties:
#Entity
public class ItemLocation {
#ManyToOne
#JoinColumn(name="fk_item_id")
public Item getItem() {
return this.item;
}
public void setItem(Item item) {
this.item = item;
}
#Id
#GeneratedValue
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
private Item item;
private long id;
}
#Entity
public class Item {
#OneToMany(mappedBy="item", orphanRemoval=true)
#Cascade({org.hibernate.annotations.CascadeType.PERSIST})
public Set<ItemLocation> getItemLocationList() {
return this.itemLocationList;
}
public void setItemLocationList(Set<ItemLocation> list) {
this.itemLocationList = list;
}
#Id
#GeneratedValue
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
private Set<ItemLocation> itemLocationList
= new HashSet<ItemLocation>();
private long id;
}
public List<ItemLocation> findAllByItem(Item item);
(in repository ItemLocationRepository)

Map one object structure to an different XML structure

I have an object similar to the following:
public class FooObj
{
private Long id;
private List<BarObj> subBar;
private String someStr;
public Long getId()
{
return id;
}
public List<BarObj> getSubBar()
{
return subBar;
}
public String getSomeStr()
{
return someStr;
}
public void setId(Long id)
{
this.id = id;
}
public void setSubBar(List<BarObj> subBar)
{
this.subBar = subBar;
}
public void setSomeStr(String someStr)
{
this.someStr = someStr;
}
public static class BarObj
{
private String groupId;
private Long id;
public String getGroupId()
{
return groupId;
}
public Long getId()
{
return id;
}
public void setGroupId(String groupId)
{
this.groupId = groupId;
}
public void setId(Long id)
{
this.id = id;
}
}
}
And I want to map the Object to an XML structure like the XML in the link: http://pastebin.com/cw018jqc EDIT:(Please look at the ObjBars element for an exact definition of what I'm looking for.)
Is there any library available that would allow me to do this?
So you're basically trying to split a list into multiple sublists before you serialize it to XML? I think that JAXB could really help you here. I think you could use an #XmlTypeAdapter to convert between List<BarObj> and List<List<BarObj>>, which would be one way of representing this data the way you want it marshalled to XML. Check out http://blog.bdoughan.com/2010/07/xmladapter-jaxbs-secret-weapon.html for details.

Marshalling an object that has object fields

Not sure if the title makes any sense.
I have an object that I want to marshal using JAXB that looks like this:
#XmlRootElement(name = "subscriptionRequest")
public class RegistrationRequest {
private Long id;
private RegistrationSource registrationSource;
}
The RegistrationSource object:
public class RegistrationSource {
private Integer id;
private String code;
}
I want to create an xml that has the following layout:
<subscriptionRequest registrationSource="0002">
...
</subscriptionRequest>
where the registrationSource attribute value is the code field value from the RegistrationSource object.
What xml annotations do I need to use?
#XmlAttribute on registrationSource, #XmlValue on code. Note that in this case you also should have #XmlTransient on other fields of RegistrationSource, such as id
EDIT: This works:
#XmlRootElement(name = "subscriptionRequest")
public class RegistrationRequest {
private Long id;
private RegistrationSource registrationSource;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
#XmlAttribute
public RegistrationSource getRegistrationSource() { return registrationSource; }
public void setRegistrationSource(RegistrationSource registrationSource)
{
this.registrationSource = registrationSource;
}
}
-
public class RegistrationSource {
private Integer id;
private String code;
#XmlTransient
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
#XmlValue
public String getCode() { return code; }
public void setCode(String code) { this.code = code; }
}
If you want to generate this class automatically using some tools , then try this -
Generate xsd from your xml using tools like Trang, and then generate java file from xsd using jaxb. Life would be much simpler :)
The lame approach would be to add something like
#XmlAttribute(name = "registrationSource")
private String getCode() {
return registrationSource.code;
}
to your RegistrationSource -- but there must be a more elegant way...

Categories

Resources