Hello.
I tried to my code in hibernate 4.1.4 final , unfortunately it does not work.
Hibernate's nullable attribute at @embedded doesn't work?
My code show below:
Code:
/**
 * Sample Entity
 * 
 * @author nobukick
 */
@Entity
@Table(name= "Sample")
public class Sample implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    @Embedded
    private EmbeddableNames embeddableNames;
    private String comment;
    public Sample() {}
    public EmbeddableNames getEmbeddableNames() {
        return embeddableNames;
    }
    public void setEmbeddableNames(EmbeddableNames embeddableNames) {
        this.embeddableNames = embeddableNames;
    }
    public String getComment() {
        return comment;
    }
    public void setComment(String comment) {
        this.comment = comment;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
}
Sample.class is JPA's entity. This embedded EmbeddableNames.class.
Code:
/**
 * Sample Attributes
 * 
 * @author nobukick
 */
@Embeddable
public class EmbeddableNames implements Serializable {
    
    /** First Name */
    @Column(name = "FirstName")
    private String firstName;
    
    /** Middle Name(nullable) */
    @Column(name = "MiddleName", nullable=true)
    private String middleName;
    
    /** Family Name */
    @Column(name = "FamilyName")
    private String familyName;
    
    public EmbeddableNames() {}
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getFamilyName() {
        return familyName;
    }
    public void setFamilyName(String familyName) {
        this.familyName = familyName;
    }
    public String getMiddleName() {
        return middleName;
    }
    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }
}
I figured middle name column is nullable, because many Asian peoples doesn't have that.
Code:
/**
 * Embedded Object Search Test
 * 
 * @author nobukick
 */
public class EmbeddableObjectSearchTest extends TestCase {
    private EntityManagerFactory entityManagerFactory;
    @Override
    protected void setUp() throws Exception {
        entityManagerFactory = Persistence.createEntityManagerFactory("testPU");
        createData();
    }
    @Override
    protected void tearDown() throws Exception {
        entityManagerFactory.close();
    }
    /**
     * create data;
     */
    private void createData() {
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        entityManager.getTransaction().begin();
        /**
         * west sample
         */
        EmbeddableNames westName = new EmbeddableNames();
        westName.setFirstName("Dorothy");
        // set middle name
        westName.setMiddleName("Walker");
        westName.setFamilyName("Bush");
        Sample westComment = new Sample();
        westComment.setEmbeddableNames(westName);
        westComment.setComment("I am Dorothy Walker Bush.");
        entityManager.persist(westComment);
        /**
         * east sample
         */
        EmbeddableNames eastName = new EmbeddableNames();
        eastName.setFirstName("Tarou");
        eastName.setFamilyName("YAMADA");
        // east name doesnot hav middlename.
        Sample eastComment = new Sample();
        eastComment.setEmbeddableNames(eastName);
        eastComment.setComment("I am tarou yamada.");
        entityManager.persist(eastComment);
        entityManager.getTransaction().commit();
        entityManager.close();
    }
    /**
     * Test west name origin
     */
    public void testWestNameOriginSearch() {
        EntityManager entityManager;
        // now lets pull events from the database and list them
        entityManager = entityManagerFactory.createEntityManager();
        entityManager.getTransaction().begin();
        
        // this case is success
        EmbeddableNames names = new EmbeddableNames();
        names.setFirstName("Dorothy");
        names.setMiddleName("Walker");
        names.setFamilyName("Bush");
        
        Sample result = entityManager.createQuery("from Sample where embeddableNames = :names ", Sample.class).setParameter("names", names).getSingleResult();
        
        entityManager.getTransaction().commit();
        entityManager.close();
    }
    /**
     * Test east name origin
     * east name does not hav middlename(eq null);
     */
    public void testEastNameOriginSearch() {
        EntityManager entityManager;
        // now lets pull events from the database and list them
        entityManager = entityManagerFactory.createEntityManager();
        entityManager.getTransaction().begin();
        EmbeddableNames names = new EmbeddableNames();
        names.setFirstName("Tarou");
        names.setFamilyName("YAMADA");
        Sample result = entityManager.createQuery("from Sample where embeddableNames = :names ", Sample.class).setParameter("names", names).getSingleResult();
        
        assertEquals(result.getComment(), "I am tarou yamada.");
        entityManager.getTransaction().commit();
        entityManager.close();
    }
}
Quote:
javax.persistence.NoResultException: No entity found for query
	at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:290)
	at net.noumin.hibernatesample.entity.EmbeddableObjectSearchTest.testEastNameOriginSearch(EmbeddableObjectSearchTest.java:109)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at junit.framework.TestCase.runTest(TestCase.java:168)
	at junit.framework.TestCase.runBare(TestCase.java:134)
	at junit.framework.TestResult$1.protect(TestResult.java:110)
	at junit.framework.TestResult.runProtected(TestResult.java:128)
	at junit.framework.TestResult.run(TestResult.java:113)
	at junit.framework.TestCase.run(TestCase.java:124)
	at junit.framework.TestSuite.runTest(TestSuite.java:243)
	at junit.framework.TestSuite.run(TestSuite.java:238)
	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
	at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
	at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115)
	at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102)
	at org.apache.maven.surefire.Surefire.run(Surefire.java:180)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
	at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
I expected EntityManager returned Tarou's entity after persisting it.
But EntityManager returned NoResultException.
How to do EntityManager returned it?
Has anyone seen this problem before?
I guess this is @embedded bugs.
Thanks