I'm brand new to Hibernate, and I'm trying to get a fairly simple Hibernate code snippet to work. After reading the tutorials, I'm totally choking on the full implementation.
For one, when it comes to the hbm2ddl.auto property, I'm setting it to validate because I just don't like the idea of Hibernate creating my table structure (I'm old fashioned; perhaps that will change as I become more comfortable with Hibernate though). In any event, here's the table I just created on a MySQL server:
CREATE TABLE users (
id INT NOT NULL AUTO INCREMENT,
email VARCHAR(200) NOT NULL,
title VARCHAR(25),
first_name VARCHAR(100),
middle_name VARCHAR(100),
last_name VARCHAR(100),
suffix VARCHAR(100),
PRIMARY KEY (id)
);
Thise corresponds to the following POJOs/entities in my app's code:
#Entity
#Table(schema="my_db", name="users")
public class User {
#Id #GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
private Integer id;
#Column(name="email")
private String email;
// ???
private PersonName personName;
public User(final String email, final PersonName personName) {
super();
setEmail(email);
setPersonName(personName);
}
// Getters and setters omitted for brevity...
}
public abstract class BaseName {
public abstract String toName();
#Override
public String toString() {
return toName();
}
}
public class PersonName extends BaseName {
private String title;
private String firstName;
private String middleName;
private String lastName;
private String suffix;
public PersonName(final String title, final String firstName, final String middleName, final String lastName, final String suffix) {
super();
setTitle(title);
setFirstName(firstName);
setMiddleName(middleName);
setLastName(lastName);
setSuffix(suffix);
}
// Getters and setters omitted for brevity...
}
What annotations/config do I need to add so that User#personName gets persisted as an embedded PersonName object inside the users table? In other words, User is an entity and contains a PersonName as an embedded objects (non-entity).
Also, any other obvious annotations I'm missing? Thanks in advance!
As suggested by user #Snow Blind, Embedded objects are what you want.
Let's start with class PersonName:
#Embeddable
public class PersonName extends BaseName {
#Column(name = "title")
private String title;
#Column(name = "first_name")
private String firstName;
#Column(name = "middle_name")
private String middleName;
#Column(name = "last_name")
private String lastName;
#Column(name = "suffix")
private String suffix;
// ...
}
Now add the #Embedded tag here:
// ...
#Embedded
private PersonName personName;
// ...
Hope this helps!
You can check the title 2.2.2.4. Embedded objects (aka components) in docs:
http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#entity-mapping-property
Related
I am using Cassandra 3.6 with Achilles. I have below designed table in Cassandra.
CREATE TABLE userVehicles (
userid text,
name text static,
surname text static,
vehicleNum text,
vehicleMake text,
vehicleModel text,
vehicleYear text,
PRIMARY KEY (userid)
);
I will be having many vehicles attached to single User and when I will select with UserId, I should get User details and all vehicle belongs to him.
How to map this in Achilles??
Updating table
CREATE TYPE Vehicle(
---------
)
And then in userVehicles table
vehicleDetails LIST<FROZEN<Vehicle>>
Tried Achillies mapping
#Table(keyspace="keyspace", table="userVehicles")
public class UserDetails{
#PartitionKey(value = 1)
private String userid ;
#Column
private String name ;
#Column
private String surname;
#Column
private List<#Frozen Vehicle> vehicle;
}
#UDT(keyspace="keyspace", name="vehicle")
public class Vehicle {
#Column
private String vehicleNum ;
#NotNull
#Column
private String vehicleMake ;
#Column
private String vehicleModel ;
#NotNull
#Column
private String vehicleYear ;
}
#Configuration
#CompileTimeConfig(cassandraVersion = CassandraVersion.CASSANDRA_3_7)
public class AchillesConfiguration {
#Autowired
ManagerFactory managerFactory;
#Bean
public User_Manager userEntityManager(){
return managerFactory.forUser();
}
}
Answer is updated in mapping above. For nested tables, this is the way you should go in Cassandra with Achilles framework.
Lets say I have this two bean entities:
public class Audit {
private String code;
private java.sql.Timestamp creationDate;
private String creatorId;
private java.sql.Timestamp deletionDate;
private String description;
private String id;
private String name;
private String notes;
private Short status;
private List<AuditParticipant> participants;
}
and :
public class AuditParticipant {
private String auditId;
private String department;
private String id;
private String name;
private String notes;
private String role;
private String surname;
}
... where Audit can have 1..n Participants, how can I use QueryDSL SQL to project the list of the participants into Audit bean (get all participants that belongs to audit)?
The beans were generated using QueryDSL code generation.
Thanks
Querydsl provides result aggregation functionality for such cases http://www.querydsl.com/static/querydsl/3.1.1/reference/html/ch03s02.html#d0e1634
In this case it would be something like
query.from(audit)
.innerJoin(participant).on(...)
.transform(groupBy(audit.id).as(audit, list(participant)));
See these examples for other groupBy options https://github.com/mysema/querydsl/blob/master/querydsl-collections/src/test/java/com/mysema/query/collections/GroupByTest.java
The following query throws the exception:
Query query = session.createQuery("from Associate as a order by a.username asc");
associates = query.list();
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [ca.mypkg.model.Associate#0]
If I create an entry in the database with id of 0 it works just fine. I don't really get it because I'm just trying to load all the entries in the db not just a specific one.
Similar questions I've found have been concerned with trying to load an object with a given ID I'm doing no such thing.
Associate class:
#Table(name = "user")
#XmlRootElement(name = "associate")
public class Associate implements Serializable {
private String username;
private String password;
private String firstName;
private String lastName;
private String userType;
private int id;
private String email;
private String isActive;
private Department dept;
private String lastUpdated;
private String associate_type;
// ...
#Id
#GeneratedValue
public int getId() {
return id;
}
#OneToOne
#JoinColumn(name = "dept")
public Department getDept() {
return dept;
}
From my experience this type of error message usually means it does not find joined entity by mentioned id, and not the entity requested in the query (Associate, in your case).
My guess is that Associate class contains a join entity which has primitive type primary key.
is it possible to bind a String attribute of an JavaClass to a column of a different table.
Example
#Entity
#Table(name = "ACCOUNTS")
public class Account {
private Long id;
private String nickname;
private String address;
#Id
#Column(name = "A_ID")
#GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Column(name="A_NICKNAME")
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
What would be the correct annotation if the address where a String in a separate table?
Separate Table
CREATE TABLE IF NOT EXISTS `Adresses` (
`ad_id` BIGINT NOT NULL AUTO_INCREMENT ,
`ad_address` VARCHAR(45) NOT NULL ,
PRIMARY KEY (`da_id`) )
ENGINE = InnoDB;
thanks
You can't define address field of your object to be stored in another table (it has its own identifier that you don't have it in your account class ) but you can define another class for address and let it have its own mapping and table then your account class will have a many to one relationship with address class.This approach can have advantages too.What if you want to add another fields to your address table ? and if there's no chance that other fields can be added to your address table why do you want to store it in a separate table ?
I'm trying to map an entity using Hibernate Annotations, so that when a record is created and saved (via cascade), an ID is automatically generated. With my current setup (or a few others I've tried) I get the following error:
...org.hibernate.exception.ConstraintViolationException:
could not insert: [com.gorkwobbler.shadowrun.karma.domain.AttributeScore]
...java.sql.SQLException:
Caused by: java.sql.SQLException: Cannot insert the value NULL into column 'id', table 'KARMA_DEV.dbo.Character'; column does not allow nulls. INSERT fails.
I can see the following insert statement being issued:
Hibernate: insert into character (version, alias, firstName, lastName) values (?, ?, ?, ?)
Clearly this is wrong, there is no "id" parameter.
My table schema, for now, is simply:
Character(
id uniqueidentifier, --primary key
alias varchar(max),
firstName varchar(max),
lastName varchar(max),
version int --for hibernate
)
I am using SQL Server 2008 R2, Express edition.
My annotations are split between a mapped superclass, DomainEntity, and a concrete class, KarmaCharacter:
#MappedSuperclass
public abstract class DomainEntity implements Serializable /* Needed for HOM retainUnsaved */ {
private static final long serialVersionUID = 1L;
private String id;
private Integer version;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Generated(value=GenerationTime.INSERT)
//#GeneratedValue(generator="hibernate-uuid.hex")
//#GenericGenerator(name="hibernate-uuid.hex", strategy="org.hibernate.id.UUIDHexGenerator", parameters=#Parameter(name="separator", value="-"))
#AccessType(value="field")
public String getId() {
return id;
}
#Version
#AccessType(value="field")
public Integer getVersion() {
return version;
}
}
#SuppressWarnings("serial")
#Entity
#Table(name="character")
public class KarmaCharacter extends DomainEntity {
private String alias;
private String lastName;
private String firstName;
private SortedSet<AttributeScore> attributeScores;
public KarmaCharacter() {
//default constructor
}
#Column
#AccessType(value="field")
public String getAlias() {
return alias;
}
#Column
#AccessType(value="field")
public String getFirstName() {
return firstName;
}
#Column
#AccessType(value="field")
public String getLastName() {
return lastName;
}
//...omitted some transient code and a collection property for brevity
public void setAlias(String alias) {
this.alias = alias;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
If someone could tell me the right way to generate uniqueidentifer-type ID's with hibernate in SQL Server, and get them to be saved properly, it would be much appreciated.
I can see the following insert statement being issued (...). Clearly this is wrong, there is no "id" parameter.
Indeed, when using the uniqueidentifier SQL Server type, Hibernate has to use newid(). But your current annotations are not telling it to do so. I think you need the guid generator here:
#Id
#GenericGenerator(name = "generator", strategy = "guid", parameters = {})
#GeneratedValue(generator = "generator")
public String getId() {
return id;
}
Some additional remarks:
The GUID column type is really meant to hold a GUID generated by Microsoft's algorithm, you can't use Hibernate's UUID algorithm.
You don't need the Generated annotation on an Id, just remove it.
I also wonder why you are "messing" wit AccessType, I would just remove them.
I would actually not use a GUID (see this article) but this is another story.