I have a to send an xml file to a spring boot controller, in this file i have a list of objects, i have to validate the xml file and, if it's valid i have to unmarshal those objects into dtos and than save in db. These are the xml file
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ListProductDTO
xsi:noNamespaceSchemaLocation="schema.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<productDTO>
<eancode>1111111111111</eancode>
<name>hamburger</name>
<price>10</price>
<weight>100</weight>
<description>a nice hamburger</description>
<quantity>1</quantity>
<categoryName>meat</categoryName>
</productDTO>
<productDTO>
<eancode>2111111111111</eancode>
<name>banana</name>
<price>6</price>
<weight>100</weight>
<description>a nice banana</description>
<quantity>1</quantity>
<categoryName> fruit</categoryName>
</productDTO>
<productDTO>
<eancode>3111111111111</eancode>
<name>apple</name>
<price>10</price>
<weight>100</weight>
<description>a nice apple</description>
<quantity>1</quantity>
<categoryName>fruit</categoryName>
</productDTO>
</ListProductDTO>
and this is the xsd schema that i use
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="listProductDTO">
<xs:complexType>
<xs:sequence>
<xs:element name="products" type="productDTO" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="productDTO">
<xs:sequence>
<xs:element name="categoryName" type="xs:string" minOccurs="0"/>
<xs:element name="description" type="xs:string" minOccurs="0"/>
<xs:element name="eancode" type="xs:string" minOccurs="0"/>
<xs:element name="name" type="xs:string" minOccurs="0"/>
<xs:element name="price" type="xs:decimal" minOccurs="0"/>
<xs:element name="quantity" type="xs:int" minOccurs="0"/>
<xs:element name="weight" type="xs:double" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
also the class that i use for conversion
#Getter
#Setter
#ToString
#AllArgsConstructor
#NoArgsConstructor
#XmlRootElement(name = "ListProductDTO")
#XmlAccessorType(XmlAccessType.FIELD)
public class ListProductDTO {
#XmlElement(name = "productDTO")
private List<ProductDTO> products ;
}
#Getter
#Setter
#RequiredArgsConstructor
#ToString
#NoArgsConstructor
#XmlRootElement(name = "productDTO")
#XmlType(propOrder = {"eancode","name","price","weight","description","quantity","categoryName"})
#XmlAccessorType(XmlAccessType.FIELD)
public class ProductDTO {
#NonNull
#NotBlank(message = "eancode cannot be blank")
#Eancode(message = "eancode not valid")
#XmlElement(name = "eancode")
private String eancode;
#NonNull
#NotBlank(message = "invalid name")
#XmlElement(name = "name")
private String name;
#NonNull
#DecimalMin(message = "invalid price", value = "0.01")
#XmlElement(name = "price")
private BigDecimal price;
#NonNull
#DecimalMin(message = "weight cannot be lesser than zero", value = "0.01")
#XmlElement(name = "weight")
private Double weight;
#XmlElement(name = "description")
private String description;
#NonNull
#Min(message = "quantity cannot be lesser than zero", value = 1)
#XmlElement(name = "quantity")
private Integer quantity;
#NonNull
#NotBlank(message = "a product must belong to a category")
#XmlElement(name = "categoryName")
private String categoryName;
this is the code that i use for setup jaxb unmarshaller and set the schema:
JAXBContext context = JAXBContext.newInstance(ListProductDTO.class,ProductDTO.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
File file = new File("src/main/resources/schemas/schema.xsd");
Schema schema = sf.newSchema(file);
unmarshaller.setSchema(schema);
ListProductDTO temp = (ListProductDTO) unmarshaller.unmarshal(tmp);
the last line of code throws this exception:
org.xml.sax.SAXParseException: cvc-elt.1.a: impossible to find the element "ListProductDTO".
how can i solve?
edit: tmp is a temporary file that i generate after i decoded the base64 econded xml file that i send to the controller
The Schema and XML you have provided are not validating against each other.
You should first check if your XML is as per the Schema, i.e. validating against the schema
Secondly you are getting :
impossible to find the element "ListProductDTO"
as there is no such element in the schema instead it is listProductDTO
Related
I'm working with jhipster, I got the following jdl format:
I've made some modification on the domains that looks like:
#Entity
#Table(name = "client_account")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class ClientAccount implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private Long id;
#NotNull
#Column(name = "first_name", nullable = false)
private String firstName;
#NotNull
#Column(name = "last_name", nullable = false)
private String lastName;
#NotNull
#Column(name = "phone", nullable = false)
private String phone;
#Column(name = "identity")
private String identity;
#Column(name = "referal")
private String referal;
#Column(name = "refered_by")
private String referedBy;
#OneToOne
#MapsId
private User user;
#OneToMany(mappedBy = "clientAccount")
private Set<Reputation> reputations = new HashSet<>();
#OneToMany(mappedBy = "clientAccount")
private Set<Trip> trips = new HashSet<>();
and the reputations domain:
#Entity
#Table(name = "reputation")
public class Reputation implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Column(name = "rate", nullable = false)
private Integer rate;
#Column(name = "comment")
private String comment;
#ManyToOne
#JsonIgnoreProperties("reputations")
private TransporterAccount transporterAccount;
#ManyToOne
#JsonIgnoreProperties("reputations")
private ClientAccount clientAccount;
The user domain:
#Entity
#Table(name = "jhi_user")
public class User extends AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Pattern(regexp = Constants.LOGIN_REGEX)
#Size(min = 1, max = 50)
#Column(length = 50, unique = true, nullable = false)
private String login;
#JsonIgnore
#NotNull
#Size(min = 60, max = 60)
#Column(name = "password_hash", length = 60, nullable = false)
private String password;
#Size(max = 50)
#Column(name = "first_name", length = 50)
private String firstName;
#Size(max = 50)
#Column(name = "last_name", length = 50)
private String lastName;
#Email
#Size(min = 5, max = 254)
#Column(length = 254, unique = true)
private String email;
#NotNull
#Column(nullable = false)
private boolean activated = false;
#Size(min = 2, max = 10)
#Column(name = "lang_key", length = 10)
private String langKey;
#Size(max = 256)
#Column(name = "image_url", length = 256)
private String imageUrl;
#Size(max = 20)
#Column(name = "activation_key", length = 20)
#JsonIgnore
private String activationKey;
#Size(max = 20)
#Column(name = "reset_key", length = 20)
#JsonIgnore
private String resetKey;
#Column(name = "reset_date")
private Instant resetDate = null;
#JsonIgnore
#ManyToMany
#JoinTable(
name = "jhi_user_authority",
joinColumns = {#JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {#JoinColumn(name = "authority_name", referencedColumnName = "name")})
#BatchSize(size = 20)
private Set<Authority> authorities = new HashSet<>();
The Transporter liquibase is mapped as follow:
<changeSet id="20200218210800-1" author="jhipster">
<createTable tableName="client_account">
<column name="user_id" type="bigint">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="first_name" type="varchar(255)">
<constraints nullable="false" />
</column>
<column name="last_name" type="varchar(255)">
<constraints nullable="false" />
</column>
<column name="phone" type="varchar(255)">
<constraints nullable="false" />
</column>
<column name="identity" type="varchar(255)">
<constraints nullable="true" />
</column>
<column name="referal" type="varchar(255)">
<constraints nullable="true" />
</column>
<column name="refered_by" type="varchar(255)">
<constraints nullable="true" />
</column>
<!-- jhipster-needle-liquibase-add-column - JHipster will add columns here, do not remove-->
</createTable>
</changeSet>
<changeSet id="20200218210800-2" author="jhipster">
<addForeignKeyConstraint baseColumnNames="user_id"
baseTableName="client_account"
constraintName="fk_client_account_user_id"
referencedColumnNames="id"
referencedTableName="jhi_user"/>
</changeSet>
and the reputations liquibase:
<changeSet id="20200218210700-1-data" author="jhipster" context="faker">
<loadData
file="config/liquibase/fake-data/reputation.csv"
separator=";"
tableName="reputation">
<column name="id" type="numeric"/>
<column name="rate" type="numeric"/>
<column name="comment" type="string"/>
<!-- jhipster-needle-liquibase-add-loadcolumn - JHipster (and/or extensions) can add load columns here, do not remove-->
</loadData>
</changeSet>
<changeSet id="20200218210700-2" author="jhipster">
<addForeignKeyConstraint baseColumnNames="transporter_account_id"
baseTableName="reputation"
constraintName="fk_reputation_transporter_account_id"
referencedColumnNames="user_id"
referencedTableName="transporter_account"/>
<addForeignKeyConstraint baseColumnNames="client_account_id"
baseTableName="reputation"
constraintName="fk_reputation_client_account_id"
referencedColumnNames="user_id"
referencedTableName="client_account"/>
</changeSet>
Still I'm getting the following stacktrace error:
select reputation0_.id as id1_14_, reputation0_.client_account_user_id
as client_a4_14_, reputation0_.comment as comment2_14_,
reputation0_.rate as rate3_14_,
reputation0_.transporter_account_user_id as transpor5_14_ from
reputation reputation0_ order by reputation0_.id asc limit ?
[42122-200] 2020-02-20 09:48:03.515 ERROR 23616 --- [ XNIO-1 task-7]
c.a.dropme.aop.logging.LoggingAspect : Exception in
com.abdrid.dropme.service.ReputationQueryService.findByCriteria() with
cause = 'org.hibernate.exception.SQLGrammarException: could not
prepare statement' and exception = 'could not prepare statement; SQL
[select reputation0_.id as id1_14_,
reputation0_.client_account_user_id as client_a4_14_,
reputation0_.comment as comment2_14_, reputation0_.rate as rate3_14_,
reputation0_.transporter_account_user_id as transpor5_14_ from
reputation reputation0_ order by reputation0_.id asc limit ?]; nested
exception is org.hibernate.exception.SQLGrammarException: could not
prepare statement'
I got a similar issue ... I added a new Field in an Entity known as title (String) and jhipster entity sub-generator worked well enough ... got no issues
code got compiled and portal was also working - but when I tried listing the entity page - the ajax call gave 500 Http Status - with internal server as "prepared statement could not be created" ...
I did
./mvnw clean integration-test
and then ran the ./mvnw normally again. All the cached code was flushed and portal started working back.
The table name you used, User, is a reserved keyword for H2 databases ?
First try to surround table name of User with double quotes. If it does not work, rename your table with a name like Employee.
There is a list of keywords that can't be used as identifiers (table names, column names and so on), unless they are quoted (surrounded with double quotes).
http://www.h2database.com/html/advanced.html#keywords
I use spring for creation rest-controller and jaxb lib for exchangin with client xml - elements, so, my model are Users, User and Property.
Users contains list of users, every user contains list of properies. To create Users with user-list elements - it works, but can't to create inner property-list for user elements.
My models are:
#XmlRootElement(name = "Users")
#NoArgsConstructor
#AllArgsConstructor
#Getter
#Setter
#XmlAccessorType(XmlAccessType.FIELD)
public class Users {
#XmlElement(name = "User")
private List<User> users;
#XmlElement(name = "UserError")
private UserError error;
}
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#XmlRootElement(name = "User")
#XmlAccessorType(XmlAccessType.FIELD)
public class User implements Serializable {
#XmlElement(name = "Id")
private String id;
#XmlElement(name = "Name")
private String name;
#XmlElement(name = "Property")
private List<Property> properties;
}
#Getter
#Setter
#NoArgsConstructor
#XmlRootElement(name = "Property")
#AllArgsConstructor
#XmlAccessorType(XmlAccessType.FIELD)
public class Property implements Serializable {
#XmlElement(name = "passport")
private String passport;
#XmlElement(name = "age")
private String age;
}
How to change jaxb model for change xml from:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Users>
<User>
<Id>fff</Id>
<Name>Alex</Name>
<Property>
<Name>passport</Name>
<Value>111-222</Value>
</Property>
<Property>
<Name>car</Name>
<Value>bmv</Value>
</Property>
</User>
</Users>
To this view presentation
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Users>
<User>
<Id>fff</Id>
<Name>Alex</Name>
<Properties>
<Property>
<Name>passport</Name>
<Value>111-222</Value>
</Property>
<Property>
<Name>car</Name>
<Value>bmv</Value>
</Property>
</Properties>
</User>
</Users>
It is easy. Just add an #XmlElementWrapper annotation to the definition of
the Java variable properties:
#XmlElementWrapper(name = "Properties")
#XmlElement(name = "Property")
private List<Property> properties;
This will add <Properties>...</Properties> around the sequence of <Property>...</Property> elements.
This question already has answers here:
JQuery, Spring MVC #RequestBody and JSON - making it work together
(5 answers)
Spring MVC + JSON = 406 Not Acceptable
(22 answers)
Closed 7 years ago.
I'm having a hard time fixing this 406 error with spring MVC. What I want to do is to make an Ajax call and get a json response. Also I'm trying to output that json using alert(js). This is how I implement it.
My Controller:
#RequestMapping(value="/search", headers="Accept=*/*", produces=MediaType.APPLICATION_JSON_VALUE) // no 'params' argument
#ResponseBody
public Customer findByFirstName() {
Customer test = new Customer();
test.setFirstName("test");
return test;
}
Customer:
#Entity
#Table(name="customer",catalog="revised_cws_db")
public class Customer implements java.io.Serializable {
#Id #GeneratedValue(strategy=IDENTITY)
#Column(name="id", unique=true, nullable=false)
private int id;
#Version #Temporal(TemporalType.TIMESTAMP)
#Column(name="timestamp", nullable=false)
private Date timestamp;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="address_id", nullable=false)
private Address address;
#Temporal(TemporalType.DATE)
#Column(name="birth_date", nullable=false, length=10)
private Date birthDate;
#Column(name="first_name", nullable=false, length=45)
private String firstName;
#Column(name="middle_name", nullable=false, length=45)
private String middleName;
#Column(name="gender", nullable=false, length=45)
private String gender;
#Column(name="contact_number", length=45)
private String contactNumber;
#Column(name="family_members_count", nullable=false, length=45)
private String familyMembersCount;
#Column(name="occupation_id", nullable=false)
private int occupationId;
#Column(name="active", nullable=false)
private boolean active;
#OneToMany(fetch=FetchType.LAZY, mappedBy="customer")
private Set<Issues> issueses = new HashSet<Issues>(0);
#OneToMany(fetch=FetchType.LAZY, mappedBy="customer")
private Set<Account> accounts = new HashSet<Account>(0);
public Customer() {
}
public Customer(int id, Address address, Date birthDate, String firstName, String middleName, String gender, String familyMembersCount, int occupationId, boolean active) {
this.id = id;
this.address = address;
this.birthDate = birthDate;
this.firstName = firstName;
this.middleName = middleName;
this.gender = gender;
this.familyMembersCount = familyMembersCount;
this.occupationId = occupationId;
this.active = active;
}
public Customer(int id, Address address, Date birthDate, String firstName, String middleName, String gender, String contactNumber, String familyMembersCount, int occupationId, boolean active, Set<Issues> issueses, Set<Account> accounts) {
this.id = id;
this.address = address;
this.birthDate = birthDate;
this.firstName = firstName;
this.middleName = middleName;
this.gender = gender;
this.contactNumber = contactNumber;
this.familyMembersCount = familyMembersCount;
this.occupationId = occupationId;
this.active = active;
this.issueses = issueses;
this.accounts = accounts;
}
//getters, setters omitted
servlet:
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<mvc:annotation-driven/>
<context:component-scan base-package="com.controller" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="cacheSeconds" value="0" />
</bean>
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.htm">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<!--
The index controller.
-->
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
jsp:
<%#taglib uri = "http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
$(document).ready(function() {
$(".search-form").keyup(function() {
if ($(this).val().length >= 2) {
$('#searchForm').submit();
}
});
$('#searchForm').submit(function(event) {
$.ajax({
dataType: 'json',
data : $(this).serialize(),
url: $(this).attr("action"),
success: function( result ) {
alert("test");
}
});
event.preventDefault();
});
});
</script>
</head>
<body>
<h1>Customers</h1>
<form id="searchForm" action="search.htm">
Search Customer:
<input class="search-form" name="firstName" placeholder="First Name">
<input type="submit">
</form>
</body>
I already added the following jars:
jackson-core-asl 1.9.13
jackson-mapper-asl 1.9.13
jackson-core 2.4.4
jackson-databind 2.4.4
jackson-annotations 2.4.4
I dont know what's wrong. I'll appreciate any suggestions.
I use hibernate(with ehcache)/spring/mysql/jsf.I'am getting data from two tables in mysql.And these tables are as follows:
User
id int (primary key)
name etc.
Lesson
id int (primary key)
lesson varchar
teacher_id int (foreign key from user(id) )
and Lesson model class:
#Entity
#Table(name = "oys_lesson")
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "myregion")
public class Lesson {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", unique = true, nullable = false)
private Integer id;
#Column(name="lesson")
private String lessonName;
#ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
#JoinColumn(name="teacher_id",nullable=false)
private User user;
//Getters and Setters
User model Class
#Entity
#Table(name = "oys_user")
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "myregion")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", unique = true, nullable = false)
private Integer id;
private String username;
etc....
#OneToOne(cascade = CascadeType.REMOVE)
#JoinTable(name = "oys_user_role", joinColumns = { #JoinColumn(name = "user_id", referencedColumnName = "id") }, inverseJoinColumns = { #JoinColumn(name = "role_id", referencedColumnName = "id") })
private Role role;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
private Set<Lesson> teacherLessons;
//Getters and Setters
I'm getting lesson list with this daoimpl.
public List<Lesson> getLessonList() {
// TODO Auto-generated method stub
String username = SecurityContextHolder.getContext()
.getAuthentication().getName();
Query query = openSession()
.createQuery(
"from Lesson l where l.user in (select id from User u where u.username=:username)");
query.setParameter("username", username);
// query.setCacheable(true);
List<Lesson> lessonList = query.list();
if (lessonList.size() > 0)
return lessonList;
return null;
}
This query is getting lessons of the current user.My jsf page below:
<h:form id="form">
<p:dataTable var="lesson" value="#{lessonManagedBean.lessonList}"
paginator="true" rows="10" rowKey="#{lesson.id}"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="5,10,15" selectionMode="single"
selection="#{lessonManagedBean.selectedLesson}" id="carTable" lazy="true">
<p:ajax event="rowSelect" listener="#{lessonManagedBean.onRowSelect}"
update=":form:lessonDetail" oncomplete="PF('lessonDialog').show()" />
<p:column headerText="id" sortBy="#{lesson.id}"
filterBy="#{lesson.id}">
<h:outputText value="#{lesson.id}" />
</p:column>
<p:column headerText="Lesson Name" sortBy="#{lesson.lessonName}"
filterBy="#{lesson.lessonName}">
<h:outputText value="#{lesson.lessonName}" />
</p:column>
</p:dataTable>
<p:dialog header="Ders Detayları" widgetVar="lessonDialog" showEffect="fade"
hideEffect="fade" resizable="false">
<p:outputPanel id="lessonDetail" style="text-align:center;">
<p:panelGrid columns="2"
rendered="#{not empty lessonManagedBean.selectedLesson}"
columnClasses="label,value">
<h:outputText value="Id:" />
<h:outputText value="#{lessonManagedBean.selectedLesson.id}" />
<h:outputText value="Lesson Name" />
<h:outputText value="#{lessonManagedBean.selectedLesson.lessonName}" />
</p:panelGrid>
</p:outputPanel>
</p:dialog>
</h:form>
When I opened this page,I get the following output in console.
Hibernate: select lesson0_.id as id0_, lesson0_.lesson as lesson0_, lesson0_.teacher_id as teacher3_0_ from oys_lesson lesson0_
where lesson0_.teacher_id in (select user1_.id from oys_user user1_
left outer join oys_user_role user1_1_ on user1_.id=user1_1_.user_id
where user1_.username=?)
When page opened,This query is running 3 times.3 of the same query.But when I selected row.dialog window opens and running the same query more 19 times.
managedBean.class
#ManagedBean
#SessionScoped
public class LessonManagedBean implements Serializable {
private Lesson selectedLesson=null;
List<Lesson> lessonList;
//Getters and Setters
Why is running the same query repeatedly?When the dialog window opens, do not need to run any query?Why it works 19 times?thanks in advance..
I solved my problem.Hibernate occurs too many queries.Because JSF calls getters multiple times.So my getList methods works multiple times.
This usually is not seen as a major problem.Because getter method is a very cheap operation.
But, if you're performing expensive business logic(db operation) in the getter method (like me),this would be re-executed everytime.So, the same query(in the getter method) works again and again.
The simplest solution:
public List<Object> getPropList(){
if(propList==null){
propList=loadListFromDb();
}
return propList;
}
For more details:
Why JSF calls getters multiple times?
Number of queries is dependent on FetchMode, by default it is FetchMode.SELECT, so it will fire select statements, change it to FetchMode.SUBSELECT or FetchMode.JOIN and check the queries.
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
#Fetch(FetchMode.SUBSELECT)
private Set<Lesson> teacherLessons;
I have an entity BaseEntity, an entity Account, an AccountRepository, a bean calling the save-method of the repository and an arquillian-test.
Running the test does not work and I do not know why. Maybe someone can tell me what I am missing.
#EqualsAndHashCode(of = "id")
#MappedSuperclass
#Getter
#Setter
public abstract class BaseEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Temporal(TemporalType.TIMESTAMP)
private Date created;
#Temporal(TemporalType.TIMESTAMP)
private Date updated;
private String entityname;
public BaseEntity() {
this.created = new Date();
this.updated = this.created;
this.entityname = UUID.randomUUID().toString();
}
#PreUpdate
#PrePersist
public void update() {
this.updated = new Date();
}
}
#Entity
#Getter
#Setter
#ToString
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Account extends BaseEntity {
#Embedded
#Valid
#NotNull
private Address address;
#Column(length = 20)
#Size(min = 6, max = 20)
#NotNull
private String telephone;
#Column(unique = true, nullable = false)
#Email
#NotNull
private String email;
#Column(length = 40)
#NotNull
private String passhash;
#Column(length = 5)
#NotNull
private Language preferredLanguage;
#Column(length = 32)
private String passwordResetKey;
#Column(length = 32)
private String emailConfirmationKey;
#NotNull
private AccountStatus status;
#Transactional
#Repository
public interface AccountRepository extends JpaRepository<Account, Long>,
CrudRepository<Account, Long> {
Account findByEmail(String email);
}
#Transactional
public class RegistrationBean {
#Inject
private AccountRepository accountRepository;
public Account register(Account _account) {
System.out.println("Id before saving: " + _account.getId());
Account account = this.accountRepository.save(_account);
System.out.println("Id after saving: " + account.getId());
System.out.println("How many accounts are there after saving? : " +
this.accountRepository.count());
return account;
}
#RunWith(Arquillian.class)
public class RegistrationTest {
#Deployment
public static WebArchive createDeployment() {
WebArchive archive = ShrinkWrap.create(WebArchive.class)
.addPackages(true, "net.company")
.addAsResource("META-INF/beans.xml", "WEB-INF/beans.xml")
.addAsResource("persistence-test.xml", "META-INF/persistence.xml");
System.out.println(archive.toString(true));
return archive;
}
#Inject
private RegistrationBean registrationBean;
#Test
public void testRegisterAndLoadPerson() {
Person person = giveMeAValidPerson();
System.out.println("************ 1 Person: " + person.toString());
person = (Person) this.registrationBean.register(person);
System.out.println("************ 2 Person: " + person.toString());
Account loadedPerson =
(this.registrationBean.getAccountByEmail(person.getEmail()));
System.out.println("*************loadedPerson: " + loadedPerson.toString());
}
}
Under META-INF I have application.properties, beans.xml and persistence.xml
application.properties:
#Database Configuration
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost/testApp
db.username=testApp
db.password=testApp
beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<jpa:repositories base-package="net.company.app.repositories" />
<context:property-placeholder location="classpath:application.properties"
ignore-resource-not-found="false"/>
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource">
<property name="driverClass" value="${db.driver}"/>
<property name="jdbcUrl" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</bean>
</beans:beans>
persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns
/persistence/persistence_2_1.xsd">
<persistence-unit name="net.company_OurAppPU" transaction-type="RESOURCE_LOCAL">
<class>net.wakeit.agency.entities.Account</class>
<class>net.wakeit.agency.entities.Person</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost
/testAgency"/>
<property name="javax.persistence.jdbc.user" value="testApp"/>
<property name="javax.persistence.jdbc.password" value="testApp"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.SunONETransactionManagerLookup"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
</properties>
</persistence-unit>
</persistence>
The Id always stays null and findAll does not give any Accounts after saving. :-
I do not see, what I am missing.
Help is highly appreciated!