DBUnit error : NoSuchTableException - spring-boot

I tried to write Unit tests for my database Services according to this example (https://github.com/21decemb/spring-boot-dbunit-example). I created dataset and test example. After I run the test I recived: org.dbunit.dataset.NoSuchTableException: orders
dataset.xml:
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<!-- CUSTOMER DATA -->
<customers id="1" name="Customer" active="1"/>
<!-- POSITION DATA -->
<positions id="1" name="POSITION1"/>
<positions id="2" name="POSITION2"/>
<positions id="3" name="POSITION3"/>
<!-- ORDER DATA -->
<orders id="1" name="order1" color="RED" express="0" date="2016-12-11 19:47:39" last_update="2016-12-11 19:47:39" parent_id="1" active="1"/>
<!--<orders id="2" name="order2" color="WHITE" customer_id="1" position_id="1" express="0" date="2016-12-11 19:47:39" last_update="2016-12-11 19:47:39" active="0"/>-->
</dataset>
The second Order Row is commented becacuse I was testing two possibilities. I know that this is because of joins. When I test only 'positions' and 'customers' (simple entities without joins) it works correctly.
My "Order" entity:
#Entity
#Table(name = "orders", schema = Config.dbSchema)
public class Order implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="POSITION_ID")
private Position position;
private short express;
private Date date;
#Column(name="LAST_UPDATE")
private Date lastUpdate;
#Column(name="parent_id")
private Long parentId;
private short active;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="CUSTOMER_ID")
private Customer customer;
#OneToMany(mappedBy = "order", fetch = FetchType.LAZY)
private List<Component> components;
//getters and setters
}
Have anyone any idea on how to fix it?
Thanks in advance.

You have to add this property in the override method setUpDatabaseConfig:
#Override
protected void setUpDatabaseConfig(DatabaseConfig config) {
config.setProperty(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
}
In addition probably you need to add the schema name like this:
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<!-- CUSTOMER DATA -->
<schemaName customers id="1" name="Customer" active="1"/>
<!-- POSITION DATA -->
<schemaName positions id="1" name="POSITION1"/>
<schemaName positions id="2" name="POSITION2"/>
<schemaName positions id="3" name="POSITION3"/>
<!-- ORDER DATA -->
<schemaName orders id="1" name="order1" color="RED" express="0" date="2016-12-11 19:47:39" last_update="2016-12-11 19:47:39" parent_id="1" active="1"/>
<!--<schemaName orders id="2" name="order2" color="WHITE" customer_id="1" position_id="1" express="0" date="2016-12-11 19:47:39" last_update="2016-12-11 19:47:39" active="0"/>-->
</dataset>

Related

How to properly map MyBatis parent relation?

I'm currently struggling on trying to map my class using MyBatis and Oracle database.
I have a table with columns ID, CODE, DESCRIPTION, PARENT, VALUE, UNITS
I have a model:
public class Parameter {
private String code;
private String description;
private String value;
private Parameter parent;
private String units;
<...>
}
and a xml mapper parameterMapper.xml:
<resultMap id="ParameterResultMap" type="Parameter">
<id property="id" column="id" />
<result property="code" column="code" />
<result property="description" column="description" />
<result property="value" column="value" />
<result property="units" column="units" />
<association property="parent"
resultMap="persistence.ParameterMapper.ParameterResultMap"
columnPrefix="parent_" />
</resultMap>
<select id="readParameter" parameterType="Parameter" resultMap="ParameterResultMap">
SELECT
p.id,
p.code,
p.description,
p.value,
p.units,
par.id AS parent_id,
par.code AS parent_code,
par.description AS parent_description,
par.value AS parent_value,
par.units AS parent_units
FROM parameter p
LEFT JOIN parameter par ON par.code = p.parent
</select>
And I get java.lang.IllegalArgumentException: Result Maps collection does not contain value for persistence.ParameterMapper.ParameterResultMap] exception on my console.
What I've done wrong and where could be the problem?
Thanks in advance!

Using finders in views

I don't understand how I can use a finder that takes a parameter to display only the returned data.
For example, I have a finder findPrincipalsByUsernameLike(String username) in Principle entity, how can I use this finder in list.jspx to show the user only his/her data?
Principle.java
#RooJavaBean
#RooToString
#RooJpaActiveRecord(table = "security_principals", finders = { "findPrincipalsByUsernameLike" })
public class Principal {
#NotNull
#Size(min = 5, max = 50)
private String username;
#NotNull
#Size(min = 5, max = 50)
private String password;
private Boolean enabled;
}
users/list.jspx
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:page="urn:jsptagdir:/WEB-INF/tags/form"
xmlns:table="urn:jsptagdir:/WEB-INF/tags/form/fields" version="2.0">
<jsp:directive.page contentType="text/html;charset=UTF-8" />
<jsp:output omit-xml-declaration="yes" />
<page:find finderName="findPrincipalsByUsernameLike"
id="ff_edu_gju_syria_model_security_principal"
path="/principals/find">
<input data-dojo-props="trim:true" data-dojo-type="dijit/form/TextBox"
id="toolbarFilter" name="filter" type="text" value="${filter}" />
</page:find>
<page:list id="pl_edu_gju_syria_model_security_Principal"
items="${principals}" z="+E0uiC5dOFGeuICZbYdoS6Nz80o=">
<table:table data="${principals}"
id="l_edu_gju_syria_model_security_Principal" path="/security/users"
z="9ue3QOERNh44QuGQIg9JQzmFKnI=">
<table:column id="c_edu_gju_syria_model_security_Principal_username"
property="username" z="REKFqtjHv0gJUiSxe+y1TKytm1w=" />
<table:column id="c_edu_gju_syria_model_security_Principal_password"
property="password" z="4khHEC8FhwrPHVFPG7c4s5cP8L4=" />
<table:column id="c_edu_gju_syria_model_security_Principal_enabled"
property="enabled" z="boq7MuGPymSQN1CCWrQ8INhy1DM=" />
</table:table>
</page:list>
</div>
How can I pass the current username without showing a text area for the user?
You don't have to send the user as request param.
In the Controller method that handles the request just get the user principal from the request.
Spring Security 3.2 introduced great improvements for easier user detail management, take a look to How to get active user's UserDetails

org.hibernate.exception.SQLGrammarException: could not get next sequence value and sequence does not exit

I'm using oracle sql developer and create a table named avatar. It has two columns , avatarid and image .
I also create a trigger and sequence for id auto generation .
But when I use this table with hibernate and spring tool suite , I got an exception ,that is
org.hibernate.exception.SQLGrammarException: could not get next
sequence value.
It says
sequence does not exit
I try all the answers but can't fix the error. In Sprig Tool Suite , I connect to database using datasource and search my sequence under my schema , and my sequence doesn't exit.
I created the sequence along with trigger using Oracle SQL Developer.
Please give me some more advice.
Here is my Avatar.hbm.xml
<hibernate-mapping>
<class name="com.bluestone.fileupload.model.Avatar" table="avatar">
<id name="avatarid" type="int">
<column name="AVATARID" />
<generator class="sequence">
<param name="my_seq">SU_AVATAR_SEQUENCE</param>
</generator>
</id>
<property name="image" type="binary">
<column name="IMAGE" not-null="true" />
</property>
</class>
</hibernate-mapping>
And , this is my Avatar.class
#Entity
#Table(name = "avatar")
public class Avatar{
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_seq")
private int avatarid;
private byte[] image;
public Avatar() {
}
public Avatar(int avatarid, byte[] image) {
super();
this.avatarid = avatarid;
this.image = image;
}
public void setAvatarid(int avatarid) {
this.avatarid = avatarid;
}
.
.
1) Make sure is the sequence is available in the database
2) May be you need to use schema say eg : HR.SU_AVATAR_SEQUENCE
where HR is the schema name
3)Else create sysnonym for schema
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "my_seq_gen_9")
#SequenceGenerator(name = "my_seq_gen_9", sequenceName = "SEQ_NAME_YOUR")
#Column(name = "COLUMN")
private long columnName;
Sequence can used as in hibernate.
I faced the same issue.
My Resolution was:
#SequenceGenerator(name = "ID_GENERATOR", sequenceName = "ACTIVITY_SEQ", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ID_GENERATOR")

JPA | One to one mapping with eager fetch

I am working with a JPA sample application with hibernate as JPA provider.
In which I am having a one to one mapping with fetch type EAGER.
Here below is my code block:
Person.java
public class Person extends Persistent implements Serializable {
private static final long serialVersionUID = 1L;
String name;
// address as composition
Address address;
String addressId;
Address.java
public class Address extends Persistent implements Serializable {
private static final long serialVersionUID = 1L;
String address;
mapping.xml
<entity name="Person" class="com.csam.mtp.wallet.wallet.Person"
access="FIELD">
<table name="person" />
<attributes>
<basic name="name">
<column name="name" length="36" nullable="false" />
</basic>
<basic name="addressid">
<column name="addressid" length="36"/>
</basic>
<one-to-one name="address" fetch="EAGER">
<join-column name="addressid"
referenced-column-name="id" insertable="false" updatable="false"
nullable="false" />
</one-to-one>
</attributes>
</entity>
<entity name="address" class="com.csam.mtp.wallet.wallet.Address"
access="FIELD">
<table name="address" />
<attributes>
<basic name="address">
<column name="address" length="36" />
</basic>
</attributes>
</entity>
DB Script
CREATE TABLE address (
id VARCHAR (50) not null,
address VARCHAR(50),
primary key(id)
);
CREATE TABLE person (
id VARCHAR (50) not null,
name VARCHAR(50),
addressid VARCHAR(50),
primary key(id),
foreign key (addressid) REFERENCES address(id),
);
Driver class
Address address = new Address();
address.setAddress("test");
address = addressRepository.save(address);
Person person = new Person("Mike");
//person.setAddressId(address.id());
try {
person = personRepository.save(person);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(personRepository.exists(person.getID()));
Person savedPerson = personRepository.findOne(person.getID());
// Asserts
assertNotNull(savedPerson);
assertNotNull(savedPerson.id());
While saving person If i don't set address id then it saves person successfully, exists returns true but find one api always returns null
while saving person if first I save address and set address id in person and save it then
It saves person successfully, exists return true and find one api return Person object with address object (as it is eager)
So here below is my query,
Is it in case of one to one mapping with eager fetch on child, child must be saved and set in parent before the saving of parent?
I tried to find out related arcticle but not able to get one, Please assist.
Thanks in advance
In your case the Address is the parent and the Person is the Child. That's because the Child points to the Parent through the addressId FK.
Because you don't have a bi-directional association, you shouldn't have insertable="false" updatable="false"
With these settings, Hibernate won't be able to include the addressId in the INSERT or the UPDATE query.
Remove insertable="false" updatable="false"
Remove the addressId column too, since you can reference it through address.id
Add cascade from Person to Address:
<one-to-one name="address" fetch="EAGER">
<join-column name="addressid"
referenced-column-name="id" nullable="false" />
<cascade>
<cascade-persist/>
<cascade-merge/>
</cascade>
</one-to-one>
Probably it would be better to have a bi-directional association so that an Address has also a reference to a Person and in that case you should probably have a one-to-many association, since an Address may have multiple Persons.
Finally got the solution with nullable=true, as below:
<one-to-one name="address" fetch="EAGER">
<join-column name="addressid"
referenced-column-name="id" insertable="false" updatable="false"
nullable="true" />
</one-to-one>

Display attributes of many to many relationship coded with #OneToMany and #ManyToOne

I'm a newbie in Spring. I think it's better to explain my problem with a little example. Let's say I have two main classes: User and Group. A User can be part of more Groups and a Group, obviously, can have more Users. So the relationship between them is many-to-many. What I would like to show, is something like this (using JSTL):
<c:forEach items="${groups}" var="group">
<c:out value="${group.name}"/> (<c:out value="${fn:length(group.users)}" />):<br />
<c:forEach items="${groups.users}" var="user">
<c:out value="${user.name}"/><br />
</c:forEach><br />
</c:forEach>
Basically, the output should be something like:
Random (2):
Joe
Bloggs
Star wars (5):
Luke
Chewbacca
Darth Vader
Princess Leia
Yoda
Nintendo (3):
Super Mario
Metroid
Zelda
I initially coded it with the classic #ManyToMany annotation, using an additional table user_has_group (created and managed by JPA) and it was working perfectly.
I needed to modify the structure since I needed the user_has_group table to have the joined_date column. To achieve it, I read online that the best solution is to create another class (i.e. UserHasGroup) and add the one-to-many relationships to this class from User and group. Doing so, it's possible to add additional attributes to the UserHasGroup class (and therefore additional columns to the user_has_group table). Something like:
User:
#Entity
#Table(name = "user")
public class User
{
#Id
#GeneratedValue
#Column
private int id;
#Column
private String alias;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<UserHasGroup> userHasGroup = new ArrayList<UserHasGroup>();
// Constructors/getters/setters
}
Group:
#Entity
#Table(name = "`group`")
public class Group
{
#Id
#GeneratedValue
#Column
private int id;
#Column
private String name;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "group")
private List<UserHasGroup> userHasGroup = new ArrayList<UserHasGroup>();
// Constructors/getters/setters
}
UserHasGroup:
#Entity
#Table(name = "user_has_group")
public class UserHasGroup
{
#Id
#GeneratedValue
#Column
private int id;
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
#ManyToOne
#JoinColumn(name = "group_id")
private Group group;
#Column
#Temporal(TemporalType.DATE)
private Date joinedDate;
// Constructors/getters/setters
}
So far, so good. All the tests run successfully and the functionality is maintained.
But I'm facing a problem with JSTL. In fact, with this new structure is obviously not possible to do group.users to iterate through the users.
What is the best way to reach the same functionality as before but with this new structure?
Thank you.
I don't see a reason why ${fn:length(group.userHasGroup)} should'n work.
The only problem you might come accross is some no active session exception. You can solve it either by
using "open session in view" interceptor (which somebody calls an anti-pattern)
manualy iterating through the list in your service method
eager fetching the relationship - i would be very carefull here as this can lead to many queries to database
Answer to additional question:
It should look somehow like this:
<c:forEach items="${groups}" var="group">
<c:out value="${group.name}"/> (<c:out value="${fn:length(group.userHasGroup)}" />):<br />
<c:forEach items="${groups.userHasGroup}" var="userHasGroup">
<c:out value="${userHasGroup.user.name}"/><br />
</c:forEach><br />

Resources